Sysctl: error setting key 'net.ipv4.conf.all.src_valid_mark': Read-only file system

Hi!

I’m in great need of some assistance. Any help is very much appreciated.

Edit: The host system is Arch Linux with the 5.6 kernel running on a x86-64 system.

The goal:
Run both WireGuard and Transmission in one Alpine-based container simultaneously.

Progress:
Transmission is up and running and torrenting files to the host machine works fine.
WireGuard is not starting up. When running wg-quick up wg0 the script is successfully reading the wg0.conf but at the end of the startup it halts.

Docker run

sudo docker run -d --rm --name wireguard-transmission
–cap-add=NET_ADMIN
–cap-add=SYS_MODULE
–sysctl=“net.ipv4.conf.all.src_valid_mark=1”
-e “USERNAME=”
-e “PASSWORD=”
-p 51820:51820/udp
-p 9091:9091
-v /mnt/lacie/docker/compose_wireguard-transmission/wireguard-config:/etc/wireguard
-v /mnt/lacie/docker/compose_wireguard-transmission/transmission-config:/etc/transmission-daemon
-v /mnt/lacie/docker/compose_wireguard-transmission/complete:/transmission/complete
-v /mnt/lacie/docker/compose_wireguard-transmission/incomplete:/transmission/incomplete
-v /mnt/lacie/docker/compose_wireguard-transmission/watch:/transmission/watch
7ef47f8600d6

Error message
/ # wg-quick up wg0

[#] ip link add wg0 type wireguard
[#] wg setconf wg0 /dev/fd/63
[#] ip -4 address add 10.64.79.154/32 dev wg0
[#] ip link set mtu 1420 up dev wg0
[#] resolvconf -a wg0 -m 0 -x
[#] wg set wg0 fwmark 51820
[#] ip -4 route add 0.0.0.0/0 dev wg0 table 51820
[#] ip -4 rule add not fwmark 51820 table 51820
[#] ip -4 rule add table main suppress_prefixlength 0
[#] sysctl -q net.ipv4.conf.all.src_valid_mark=1
sysctl: error setting key ‘net.ipv4.conf.all.src_valid_mark’: Read-only file system
[#] resolvconf -d wg0 -f
[#] ip -4 rule delete table 51820
[#] ip -4 rule delete table main suppress_prefixlength 0
[#] ip link delete dev wg0

Dockerfile

based on alpine linux

FROM alpine:latest

maintainer

LABEL maintainer “Sebastian Danielsson sebastian.danielsson@protonmail.com

install wireguard-tools transmission-daemon

RUN apk --no-cache --virtual add wireguard-tools transmission-daemon curl

create necessary folders

RUN mkdir -p /etc/wireguard
&& mkdir -p /etc/transmission-daemon
&& mkdir -p /transmission/complete
&& mkdir -p /transmission/incomplete
&& mkdir -p /transmission/watch

copy placeholder config files and startup script from host

COPY root/ .

create volumes to load config files from host and save downloaded files to host

VOLUME [“/etc/wireguard”]
VOLUME [“/etc/transmission-daemon”]
VOLUME [“/transmission/complete”]
VOLUME [“/transmission/incomplete”]
VOLUME [“/transmission/watch”]

open ports, 51820 for wireguard, 9091 for transmission-rpc, shouldn’t need to open other ports for transmission since all traffic will be routed through the vpn over port 51820

EXPOSE 51820/udp 9091

make the startup script executable and run it

RUN chmod 700 /entrypoint.sh
ENTRYPOINT [ “/entrypoint.sh” ]

entrypoint.sh

#!/bin/sh
cd /etc/wireguard

if [ ! -f wg0.conf ]
then
echo “Could not find wg0.conf.”
fi

if [ -f wg0.conf ]
then
chmod 600 wg0.conf
wg-quick up wg0
fi

exec /usr/bin/transmission-daemon --foreground --config-dir /etc/transmission-daemon

You might want to try :

-v /sys:/sys:rw

Still getting the same error. I might add that the host system is an Arch Linux installation running on a x86-64 system if that helps.

I guessed that since otherwise you would have said it upfront.
Beside, as far as docker is concerned, imho, arch or ubuntu, debian, centos, it’s all the same (devuan or alpine might differ though)

I dont see any other clean way to get /sys mounted as RW (that doesnt mean there’s no way. --privileged might work, but that’s not a clean option)
I hope someone have a better option for you

I Googled a bit more and found this:

Looks like you can’t set any sysctl containing .net,

However I’m seeing a lot of other Docker containers doing exactly that successfully. Could anyone explain that?

I’m running into this same issue with the same goal, host Ubuntu 18.04. I have been unable to get Wireguard working in a container with anything I’ve written myself or grabbed from posts. I’ve tried the LinuxServer wireguard image as a client but am getting the same erros as @sebdanielsson . I can’t say for sure that’s the issue, but is the only thing I can see that doesn’t look right.

I’m willing to help debug this though, and will continue to look into it myself!

Does running with --privileged resolve the issue?

That’s what I had to do for https://hub.docker.com/r/jordanpotter/wireguard as well.

Actually I found this:

This guys container is actually working just by running:

Docker run

sudo docker run
–name wireguard
-v /etc/wireguard:/etc/wireguard
-p 51820:51820/udp
–cap-add NET_ADMIN
–tty --interactive
felixfischer/wireguard:latest

Without need for --privileged. I’m trying to figure out why his script is working so well when my isn’t… Do you have any idéa? :wink:

It looks like that Docker image hasn’t been updated in over a year, which means it likely isn’t running a recent version of Wireguard. The change requiring net.ipv4.conf.all.src_valid_mark appears to be recent. To verify this, you can try building his image yourself via docker build and running it.

Note that jordanpotter/wireguard also didn’t require --privileged until the image was updated to use the latest Wireguard.

That’s really interesting. I can confirm that my image is working with the --privileged option.
So is this due to a kernel change or a wireguard-tools change? Did this change before WireGuard was mainlined into 5.6?

Hello, a little late to the party but I’ve found a good fix.
include this line into the Dockerfile

RUN sed -i 's|\[\[ $proto == -4 \]\] && cmd sysctl -q net\.ipv4\.conf\.all\.src_valid_mark=1|[[ $proto == -4 ]] \&\& [[ $(sysctl -n net.ipv4.conf.all.src_valid_mark) != 1 ]] \&\& cmd sysctl -q net.ipv4.conf.all.src_valid_mark=1|' /usr/bin/wg-quick && \

And include the following option in docker compose (or the cli equivalent)

    sysctls:
      - net.ipv4.conf.all.src_valid_mark=1

This change makes wg-quick attempt to modify the value of net.ipv4.conf.all.src_valid_mark only when its not already set to 1. Docker compose sets it to 1 so the illegal operation never occurs.

I found this solution in the linuxserver/wireguard Dockerfile