Podman (Podman Desktop) 導入

ネットワーク

podman-network-create — Podman documentation

podman network create [options ] [name ]

Create a network with a static ipv4 and ipv6 subnet and set a gateway.

$ podman network create --subnet 192.168.55.0/24 --gateway 192.168.55.3 --subnet fd52:2a5a:747e:3acd::/64 --gateway fd52:2a5a:747e:3acd::10 podman4

Linuxの特権ポート(1024未満)にルートレスモードのコンテナをバインドする方法

https://linuxconfig.org/how-to-bind-a-rootless-container-to-a-privileged-port-on-linux

注)上記のルールではOUTPUTに追加しているが、PREROUTINGに追加。

1 : nftablesでポートリダイレクトルールを追加

$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443
$ sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

注)ufwを使用している場合、ufwはiptables-nft(iptables)をバックエンドで使用しているためiptablesコマンドを使用すること。

ルールの確認(# handle:ハンドル番号の表示)これはnftでも可。

$ sudo nft -a list table ip nat
.....
.....
    chain PREROUTING { # handle 2
		type nat hook prerouting priority dstnat; policy accept;
		fib daddr type local counter packets 0 bytes 0 jump DOCKER # handle 3
		tcp dport 80 counter packets 0 bytes 0 redirect to :8080 # handle 44
		tcp dport 443 counter packets 0 bytes 0 redirect to :8443 # handle 45
	}
.....
.....

$ sudo nft -a list table ip6 nat

.....
.....
    chain PREROUTING { # handle 2
		type nat hook prerouting priority dstnat; policy accept;
		fib daddr type local counter packets 6681 bytes 530912 jump DOCKER # handle 3
		tcp dport 80 counter packets 0 bytes 0 redirect to :9080 # handle 14
		tcp dport 443 counter packets 10 bytes 800 redirect to :9443 # handle 15
	}
.....
.....
        

ルールを削除

$ sudo nft delete rule ip6 nat PREROUTING handle 14

systemdで起動時にルール適用

① スクリプトを作成

まず、iptables_redirect.sh を作成し、実行権限を付与

$ sudo nano /usr/local/bin/iptables_redirect.sh
#!/bin/bash

# IPv4 ルール
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

# IPv6 ルール
ip6tables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
ip6tables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8443

保存して、実行権限を付与:

$ sudo chmod +x /usr/local/bin/iptables_redirect.sh

② systemd サービスを作成

$ sudo nano /etc/systemd/system/iptables_redirect.service
[Unit]
Description=Set iptables NAT rules for local redirection
After=network.target

[Service]
Type=oneshot
ExecStart=/usr/local/bin/iptables_redirect.sh
RemainAfterExit=yes

[Install]
WantedBy=multi-user.target

保存したら、以下のコマンドで有効化:

$ sudo systemctl enable iptables_redirect
$ sudo systemctl start iptables_redirect

2 : redirでポートリダイレクト

$ sudo apt install redir
$ sudo redir :80 127.0.0.1:8080

システムデーモンへ登録
/etc/systemd/system/redir.service

[Unit]
Description=Redirect tcp port 80 to 8080 with redir

[Service]
ExecStart=/bin/redir -sn :80 127.0.0.1:8080

[Install]
WantedBy=multi-user.target

起動

$ sudo systemctl enable --now redir.service

3 : CAP_NET_BIND_SERVICE

capabilities(7) - Linux manual page

CAP_NET_BIND_SERVICE
Bind a socket to Internet domain privileged ports (port
numbers less than 1024).

$ sudo setcap cap_net_bind_service=ep /usr/bin/rootlesskit

setcap コマンドの cap_net_bind_service=ep における ep は、 Effective (有効) と Permitted (許可) の2つのケーパビリティセットを指定するフラグです。

ep の意味:

  • e (Effective) : 実行時にこのケーパビリティを有効にする
  • p (Permitted) : プロセスがこのケーパビリティを保持することを許可する

つまり、 /usr/bin/rootlesskitcap_net_bind_service=ep を設定すると、このバイナリを実行するプロセスは 1024未満のポート (例: 80, 443) を root権限なし でバインドできるようになります。

解除

$ sudo setcap -r /usr/bin/rootlesskit

4 : 非特権ポートへ移行

ポート80以上が非特権ポートになります。

$ echo 80 | sudo tee /proc/sys/net/ipv4/ip_unprivileged_port_start

システムのデフォルトとして登録

$ echo net.ipv4.ip_unprivileged_port_start = 80 | sudo tee /etc/sysctl.d/90-unprivileged_port_start.conf

コンテナ起動時のネットワークオプション

podman-run — Podman documentation

–network=mode, –net

Set the network mode for the container.

Valid mode values are:

  • bridge[:OPTIONS,…]: Create a network stack on the default bridge. This is the default for rootful containers. It is possible to specify these additional options:
    • alias= name: Add network-scoped alias for the container.
    • ip= IPv4: Specify a static IPv4 address for this container.
    • ip6= IPv6: Specify a static IPv6 address for this container.
    • mac= MAC: Specify a static MAC address for this container.
    • interface_name= name: Specify a name for the created network interface inside the container.
    • host_interface_name= name: Specify a name for the created network interface outside the container.Any other options will be passed through to netavark without validation. This can be useful to pass arguments to netavark plugins.For example, to set a static ipv4 address and a static mac address, use --network bridge:ip=10.88.0.10,mac=44:33:22:11:00:99.
  • [:OPTIONS,…]: Connect to a user-defined network; this is the network name or ID from a network created by podman network create. It is possible to specify the same options described under the bridge mode above. Use the –network option multiple times to specify additional networks.
    For backwards compatibility it is also possible to specify comma-separated networks on the first –network argument, however this prevents you from using the options described under the bridge section above.
  • none: Create a network namespace for the container but do not configure network interfaces for it, thus the container has no network connectivity.
  • container: id: Reuse another container’s network stack.
  • host: Do not create a network namespace, the container uses the host’s network. Note: The host mode gives the container full access to local system services such as D-bus and is therefore considered insecure.
  • ns: path: Path to a network namespace to join.
  • private: Create a new namespace for the container. This uses the bridge mode for rootful containers and slirp4netns for rootless ones.
  • slirp4netns[:OPTIONS,…]: use slirp4netns(1) to create a user network stack. It is possible to specify these additional options, they can also be set with network_cmd_options in containers.conf:
    • allow_host_loopback=true|false: Allow slirp4netns to reach the host loopback IP (default is 10.0.2.2 or the second IP from slirp4netns cidr subnet when changed, see the cidr option below). The default is false.
    • mtu= MTU: Specify the MTU to use for this network. (Default is 65520).
    • cidr= CIDR: Specify ip range to use for this network. (Default is 10.0.2.0/24).
    • enable_ipv6=true|false: Enable IPv6. Default is true. (Required for outbound_addr6).
    • outbound_addr= INTERFACE: Specify the outbound interface slirp binds to (ipv4 traffic only).
    • outbound_addr= IPv4: Specify the outbound ipv4 address slirp binds to.
    • outbound_addr6= INTERFACE: Specify the outbound interface slirp binds to (ipv6 traffic only).
    • outbound_addr6= IPv6: Specify the outbound ipv6 address slirp binds to.
    • port_handler=rootlesskit: Use rootlesskit for port forwarding. Default.
      Note: Rootlesskit changes the source IP address of incoming packets to an IP address in the container network namespace, usually 10.0.2.100. If the application requires the real source IP address, e.g. web server logs, use the slirp4netns port handler. The rootlesskit port handler is also used for rootless containers when connected to user-defined networks.
    • port_handler=slirp4netns: Use the slirp4netns port forwarding, it is slower than rootlesskit but preserves the correct source IP address. This port handler cannot be used for user-defined networks.
  • pasta[:OPTIONS,…]: use pasta(1) to create a user-mode networking stack.
    This is the default for rootless containers and only supported in rootless mode.
    By default, IPv4 and IPv6 addresses and routes, as well as the pod interface name, are copied from the host. If port forwarding isn’t configured, ports are forwarded dynamically as services are bound on either side (init namespace or container namespace). Port forwarding preserves the original source IP address. Options described in pasta(1) can be specified as comma-separated arguments.
    In terms of pasta(1) options, –config-net is given by default, in order to configure networking when the container is started, and –no-map-gw is also assumed by default, to avoid direct access from container to host using the gateway address. The latter can be overridden by passing –map-gw in the pasta-specific options (despite not being an actual pasta(1) option).
    Also, -t none and -u none are passed if, respectively, no TCP or UDP port forwarding from host to container is configured, to disable automatic port forwarding based on bound ports. Similarly, -T none and -U none are given to disable the same functionality from container to host.
    Some examples:
    • pasta:–map-gw: Allow the container to directly reach the host using the gateway address.
    • pasta:–mtu,1500: Specify a 1500 bytes MTU for the tap interface in the container.
    • pasta:–ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,–dns-forward,10.0.2.3,-m,1500,–no-ndp,–no-dhcpv6,–no-dhcp, equivalent to default slirp4netns(1) options: disable IPv6, assign 10.0.2.0/24 to the tap0 interface in the container, with gateway 10.0.2.3, enable DNS forwarder reachable at 10.0.2.3, set MTU to 1500 bytes, disable NDP, DHCPv6 and DHCP support.
    • pasta:-I,tap0,–ipv4-only,-a,10.0.2.0,-n,24,-g,10.0.2.2,–dns-forward,10.0.2.3,–no-ndp,–no-dhcpv6,–no-dhcp, equivalent to default slirp4netns(1) options with Podman overrides: same as above, but leave the MTU to 65520 bytes
    • pasta:-t,auto,-u,auto,-T,auto,-U,auto: enable automatic port forwarding based on observed bound ports from both host and container sides
    • pasta:-T,5201: enable forwarding of TCP port 5201 from container to host, using the loopback interface instead of the tap interface for improved performance

Invalid if using –dns, –dns-option, or –dns-search with –network set to none or container: id.

If used together with –pod, the container joins the pod’s network namespace.