fix(gateway): Remove /dev/net/tun requirement and clean up upgrade script (#3392)

* Clean up gateway upgrade script
* Fixes #3226 to remove another place where things can go wrong when
upgrading gateways
This commit is contained in:
Jamil
2024-01-28 20:19:59 -08:00
committed by GitHub
parent f3eb2a28a5
commit 16f5401a73
7 changed files with 39 additions and 14 deletions

View File

@@ -128,8 +128,6 @@ services:
- NET_ADMIN
sysctls:
- net.ipv6.conf.all.disable_ipv6=0
devices:
- "/dev/net/tun:/dev/net/tun"
depends_on:
gateway:
condition: "service_healthy"
@@ -169,8 +167,6 @@ services:
- net.ipv6.conf.all.disable_ipv6=0
- net.ipv6.conf.all.forwarding=1
- net.ipv6.conf.default.forwarding=1
devices:
- "/dev/net/tun:/dev/net/tun"
depends_on:
api:
condition: "service_healthy"

View File

@@ -265,7 +265,6 @@ defmodule Web.RelayGroups.NewToken do
"--sysctl net.ipv6.conf.all.disable_ipv6=0",
"--sysctl net.ipv6.conf.all.forwarding=1",
"--sysctl net.ipv6.conf.default.forwarding=1",
"--device=\"/dev/net/tun:/dev/net/tun\"",
Enum.map(env, fn {key, value} -> "--env #{key}=\"#{value}\"" end),
"--env FIREZONE_NAME=$(hostname)",
"#{Domain.Config.fetch_env!(:domain, :docker_registry)}/relay:#{major_minor_version()}"

View File

@@ -180,7 +180,6 @@ defmodule Web.Sites.NewToken do
"--sysctl net.ipv6.conf.all.disable_ipv6=0",
"--sysctl net.ipv6.conf.all.forwarding=1",
"--sysctl net.ipv6.conf.default.forwarding=1",
"--device=\"/dev/net/tun:/dev/net/tun\"",
Enum.map(env ++ [{"FIREZONE_ENABLE_MASQUERADE", "1"}], fn {key, value} ->
"--env #{key}=\"#{value}\""
end),

View File

@@ -5,16 +5,21 @@ use futures_util::future::BoxFuture;
use futures_util::FutureExt;
use ip_network::IpNetwork;
use libc::{
close, fcntl, open, F_GETFL, F_SETFL, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_TUN, O_NONBLOCK, O_RDWR,
close, fcntl, makedev, mknod, open, F_GETFL, F_SETFL, IFF_MULTI_QUEUE, IFF_NO_PI, IFF_TUN,
O_NONBLOCK, O_RDWR, S_IFCHR,
};
use netlink_packet_route::RT_SCOPE_UNIVERSE;
use parking_lot::Mutex;
use rtnetlink::{new_connection, Error::NetlinkError, Handle};
use std::net::IpAddr;
use std::path::Path;
use std::task::{Context, Poll};
use std::{
fmt, io,
os::fd::{AsRawFd, RawFd},
fmt, fs, io,
os::{
fd::{AsRawFd, RawFd},
unix::fs::PermissionsExt,
},
};
use tokio::io::unix::AsyncFd;
@@ -25,6 +30,8 @@ pub(crate) const SIOCGIFMTU: libc::c_ulong = libc::SIOCGIFMTU;
const IFACE_NAME: &str = "tun-firezone";
const TUNSETIFF: libc::c_ulong = 0x4004_54ca;
const TUN_FILE: &[u8] = b"/dev/net/tun\0";
const TUN_DEV_MAJOR: u32 = 10;
const TUN_DEV_MINOR: u32 = 200;
const RT_PROT_STATIC: u8 = 4;
const DEFAULT_MTU: u32 = 1280;
const FILE_ALREADY_EXISTS: i32 = -17;
@@ -82,6 +89,8 @@ impl Tun {
}
pub fn new(config: &InterfaceConfig, _: Vec<IpAddr>, _: &impl Callbacks) -> Result<Self> {
create_tun_device()?;
let fd = match unsafe { open(TUN_FILE.as_ptr() as _, O_RDWR) } {
-1 => return Err(get_last_error()),
fd => fd,
@@ -232,6 +241,31 @@ fn set_non_blocking(fd: RawFd) -> Result<()> {
}
}
fn create_tun_device() -> Result<()> {
let path = Path::new(std::str::from_utf8(TUN_FILE).unwrap());
if path.exists() {
return Ok(());
}
let parent_dir = path.parent().unwrap();
fs::create_dir_all(parent_dir)?;
let permissions = fs::Permissions::from_mode(0o751);
fs::set_permissions(parent_dir, permissions)?;
if unsafe {
mknod(
TUN_FILE.as_ptr() as _,
S_IFCHR,
makedev(TUN_DEV_MAJOR, TUN_DEV_MINOR),
)
} != 0
{
return Err(get_last_error());
}
Ok(())
}
/// Read from the given file descriptor in the buffer.
fn read(fd: RawFd, dst: &mut [u8]) -> io::Result<usize> {
// Safety: Within this module, the file descriptor is always valid.

View File

@@ -3,8 +3,6 @@
set -e
TARGET_IMAGE="ghcr.io/firezone/gateway:1"
REPO=$(dirname "$TARGET_IMAGE")
IMAGE=$(basename "$TARGET_IMAGE")
CURRENTLY_RUNNING=$(docker ps --format "{{.Names}} {{.Image}}" | grep -e "$TARGET_IMAGE" | awk '{print $1}')
if [ "$CURRENTLY_RUNNING" == "" ]; then
@@ -40,7 +38,6 @@ do
--sysctl net.ipv6.conf.all.disable_ipv6=0 \
--sysctl net.ipv6.conf.all.forwarding=1 \
--sysctl net.ipv6.conf.default.forwarding=1 \
--device="/dev/net/tun:/dev/net/tun" \
"$TARGET_IMAGE"
rm variables.env
echo "Container upgraded"

View File

@@ -24,7 +24,7 @@ write_files:
ExecStartPre=-/usr/bin/docker stop ${container_name}
ExecStartPre=-/usr/bin/docker rm ${container_name}
ExecStartPre=/usr/bin/docker pull ${container_image}
ExecStart=/bin/sh -c 'docker run --rm --name=${container_name} --cap-add=NET_ADMIN --volume /etc/firezone --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.conf.all.src_valid_mark=1 --sysctl net.ipv6.conf.all.disable_ipv6=0 --sysctl net.ipv6.conf.all.forwarding=1 --sysctl net.ipv6.conf.default.forwarding=1 --device="/dev/net/tun:/dev/net/tun" --env FIREZONE_NAME=$(hostname) --env FIREZONE_ID=$(echo $RANDOM$(hostname) | md5sum | head -c 20; echo;) --env-file="/etc/firezone-gateway/env" ${container_image}'
ExecStart=/bin/sh -c 'docker run --rm --name=${container_name} --cap-add=NET_ADMIN --volume /etc/firezone --sysctl net.ipv4.ip_forward=1 --sysctl net.ipv4.conf.all.src_valid_mark=1 --sysctl net.ipv6.conf.all.disable_ipv6=0 --sysctl net.ipv6.conf.all.forwarding=1 --sysctl net.ipv6.conf.default.forwarding=1 --env FIREZONE_NAME=$(hostname) --env FIREZONE_ID=$(echo $RANDOM$(hostname) | md5sum | head -c 20; echo;) --env-file="/etc/firezone-gateway/env" ${container_image}'
ExecStop=/usr/bin/docker stop gateway
ExecStopPost=/usr/bin/docker rm gateway

View File

@@ -107,7 +107,7 @@ write_files:
TimeoutStartSec=0
Restart=always
ExecStartPre=/usr/bin/docker pull ${container_image}
ExecStart=/bin/sh -c 'docker run --rm --name=${container_name} --cap-add=NET_ADMIN --volume /etc/firezone --device="/dev/net/tun:/dev/net/tun" --env FIREZONE_NAME=$(hostname) --env FIREZONE_ID=$(echo $RANDOM$(hostname) | md5sum | head -c 20; echo;) --env-file="/etc/firezone-gateway/.env" ${container_image}'
ExecStart=/bin/sh -c 'docker run --rm --name=${container_name} --cap-add=NET_ADMIN --volume /etc/firezone --env FIREZONE_NAME=$(hostname) --env FIREZONE_ID=$(echo $RANDOM$(hostname) | md5sum | head -c 20; echo;) --env-file="/etc/firezone-gateway/.env" ${container_image}'
ExecStop=/usr/bin/docker stop gateway
ExecStopPost=/usr/bin/docker rm gateway