{{ ansible_managed | comment }} [Unit] Description=Relay {{ item.name }} ({{ item.listen_address }}:{{ item.listen_port }} -> {{ item.target }}) After=network-online.target wg-quick@{{ wg_interface }}.service Wants=network-online.target {% if item.direction == 'inbound' %} # Inbound listeners bind to the tunnel address, which doesn't exist until # wg-quick has brought the interface up. BindsTo=wg-quick@{{ wg_interface }}.service {% endif %} [Service] Type=simple ExecStart=/usr/bin/socat -d \ TCP-LISTEN:{{ item.listen_port }},bind={{ item.listen_address }},fork,reuseaddr,keepalive,keepidle=60,keepintvl=10,keepcnt=5 \ TCP:{{ item.target }},keepalive,keepidle=60,keepintvl=10,keepcnt=5 # Bind may fail for a few seconds after boot while wg0 settles; just retry. Restart=always RestartSec=5 # socat needs no privileges beyond binding a high port. User={{ socat_user }} Group={{ socat_group }} NoNewPrivileges=yes PrivateTmp=yes PrivateDevices=yes ProtectSystem=strict ProtectHome=yes ProtectKernelTunables=yes ProtectKernelModules=yes ProtectControlGroups=yes RestrictAddressFamilies=AF_INET AF_INET6 RestrictNamespaces=yes MemoryDenyWriteExecute=yes CapabilityBoundingSet= [Install] WantedBy=multi-user.target