networking/nsupdate.nix
networking/upnpc.nix
networking/wireless.nix
+ networking/openvpn.nix
];
boot.initrd.network = {
enable = true;
ruleset = lib.mkBefore ''
table inet filter {
- # A set containing the udp port(s) to which SSDP replies are allowed.
- set ssdp_out {
- type inet_service
- timeout 5s
- }
- set lograte4 { type ipv4_addr; size 65535; flags dynamic; }
- set lograte6 { type ipv6_addr; size 65535; flags dynamic; }
- chain block {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "block: "
- add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: "
- counter drop
- }
- chain ping-flood {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: "
- add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: "
- counter drop
- }
- chain smurf {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: "
- add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: "
- counter drop
- }
- chain bogus-tcp {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
- add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
- counter drop
- }
- chain syn-flood {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: "
- add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: "
- counter drop
- }
- chain check-tcp {
- tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp
- tcp flags & (ack|fin) == fin counter goto bogus-tcp
- tcp flags & (ack|psh) == psh counter goto bogus-tcp
- tcp flags & (ack|urg) == urg counter goto bogus-tcp
- tcp flags & (fin|ack) == fin counter goto bogus-tcp
- tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp
- tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp
- tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan"
- tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan"
- tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan"
- tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan"
- tcp flags == (fin|urg|psh) counter goto bogus-tcp
- tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID"
- tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp
-
- ct state new tcp flags != syn counter goto bogus-tcp
- tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp
- tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood
- }
+ include "${../../../var/nftables/filter.txt}"
chain net2fw {
#udp dport mdns ip6 daddr ff02::fb counter accept comment "Accept mDNS"
#udp dport mdns ip daddr 224.0.0.251 counter accept comment "Accept mDNS"
chain extra2fw {
# Some .nix append rules here with: add rule inet filter extra2fw ...
}
- chain accept-icmpv6 {
- # Traffic That Must Not Be Dropped
- # https://tools.ietf.org/html/rfc4890#section-4.4.1
- icmpv6 type destination-unreachable counter accept
- icmpv6 type packet-too-big counter accept
- icmpv6 type time-exceeded counter accept
- icmpv6 type parameter-problem counter accept
-
- # Address Configuration and Router Selection messages
- # (must be received with hop limit = 255)
- icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept
- icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept
- icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept
- icmpv6 type nd-redirect ip6 hoplimit 255 log level warn prefix "icmpv6: nd-redirect: " counter drop
- icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept
- icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept
-
- # Link-local multicast receiver notification messages
- # (must have link-local source address)
- icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept
- icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept
- icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept
- # https://tools.ietf.org/html/rfc3810 Multicast Listener Discovery Version 2 (MLDv2) for IPv6
- icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept
-
- # SEND Certificate Path notification messages
- # (must be received with hop limit = 255)
- icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation"
- icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement"
-
- # Multicast Router Discovery messages
- # (must have link-local source address and hop limit = 1)
- icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement"
- icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation"
- icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination"
- }
chain input {
type filter hook input priority filter
iifname lo accept
jump check-tcp
-
ct state { established, related } accept
-
- # Connectivity checking messages
- # (multicast) ping
- ip protocol icmp icmp type echo-reply counter accept
-
- ${lib.optionalString networking.enableIPv6 ''
- # drop packets with rh0 headers
- rt type 0 jump block
- rt type 0 jump block
- rt type 0 jump block
-
- # (multicast) ping
- ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
-
- #ip6 daddr fe80::/64 udp dport 546 counter accept comment "DHCPv6"
- ''}
-
+ jump accept-connectivity-input
ct state invalid counter drop
- ip protocol icmp icmp type destination-unreachable counter accept
- ip protocol icmp icmp type time-exceeded counter accept
- ip protocol icmp icmp type parameter-problem counter accept
- ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- ip protocol icmp icmp type echo-request counter accept
- # echo-reply is handled before invalid packets to allow multicast ping
- # which do not have an associated connection.
-
- #ip daddr 224.0.0.251 udp dport 5353 counter accept comment "mDNS"
- #ip saddr 0.0.0.0/32 counter accept comment "DHCP"
- #ip udp sport 67 udp dport 68 counter accept comment "DHCP"
-
- ${lib.optionalString networking.enableIPv6 ''
- ip6 nexthdr ipv6-icmp jump accept-icmpv6
-
- # Connectivity checking messages
- icmpv6 type echo-request counter accept
- # echo-reply is handled before invalid because of multicast
-
- ip6 nexthdr ipv6-icmp log level err prefix "net2fw: icmpv6: catch all: " counter reject
-
- ip6 daddr ff02::fb udp dport 5353 counter accept comment "mDNS"
- ''}
-
- ip saddr 224.0.0.0/4 counter goto smurf
- fib saddr type broadcast counter goto smurf
-
# admin services
tcp dport 22 counter accept comment "SSH"
udp dport 60000-61000 counter accept comment "Mosh"
policy drop
ct state { related, established } accept
-
- ip protocol icmp icmp type destination-unreachable counter accept
- ip protocol icmp icmp type time-exceeded counter accept
- ip protocol icmp icmp type parameter-problem counter accept
- ip protocol icmp icmp type echo-request counter accept
-
- ${lib.optionalString networking.enableIPv6 ''
- # Traffic That Must Not Be Dropped
- # https://tools.ietf.org/html/rfc4890#section-4.3.1
- ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
-
- # Connectivity checking messages
- ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
-
- # Traffic That Normally Should Not Be Dropped
- # https://tools.ietf.org/html/rfc4890#section-4.3.2
- ip6 nexthdr ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request"
- ip6 nexthdr ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply"
- ip6 nexthdr ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation"
- ip6 nexthdr ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement"
- ''}
+ jump accept-connectivity-forward
}
chain output {
type filter hook output priority filter
oifname lo accept
ct state { related, established } accept
-
- ip protocol icmp counter accept
- meta skuid 0 udp dport 33434-33523 counter accept comment "traceroute"
-
- ${lib.optionalString networking.enableIPv6 ''
- ip6 nexthdr ipv6-icmp jump accept-icmpv6
-
- # Connectivity checking messages
- ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
- ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
- ip6 nexthdr ipv6-icmp log level err prefix "fw2net: icmpv6: catch all: " counter reject
-
- ip6 daddr ff02::1:2/64 udp dport 547 counter accept comment "DHCPv6"
- ''}
-
- ct state invalid log level warn prefix "fw2net: invalid: " counter drop
+ jump accept-connectivity-output
tcp dport 22 counter accept comment "SSH"
--- /dev/null
+{
+imports = [
+ openvpn/riseup.nix
+];
+}
--- /dev/null
+{ pkgs, lib, config, ... }:
+let
+ ns = "riseup";
+ dev = "ov-${ns}";
+ inherit (config.services) openvpn;
+in
+{
+networking.nftables.ruleset = ''
+ add rule inet filter fw2net tcp dport {443,1194} counter accept comment "OpenVPN"
+'';
+systemd.services."openvpn-${ns}" = {
+ bindsTo = [ "netns@${ns}.service" ];
+ requires = [ "netns@${ns}.service" ];
+};
+services.openvpn.servers = {
+ "${ns}" = {
+ config = ''
+ verb 3
+ ca ${riseup/cacert.pem}
+ cert ${riseup/client.pem}
+ client
+ dev ov-${ns}
+ dev-type tun
+ persist-tun
+ nobind
+ # Useless to setup the interface
+ # because moving it to ${ns} will reset it
+ ifconfig-noexec
+ route-noexec
+ persist-key
+ key ${riseup/client.pem}
+ tls-client
+ remote-cert-tls server
+ remote 37.218.241.7 1194 tcp4
+ remote 37.218.241.106 443 tcp4
+ remote 163.172.126.44 443 tcp4
+ remote 198.252.153.28 443 tcp4
+ remote 199.58.81.143 443 tcp4
+ remote 199.58.81.145 443 tcp4
+ remote 212.83.143.67 443 tcp4
+ remote 212.83.144.12 443 tcp4
+ remote 212.83.146.228 443 tcp4
+ remote 212.83.165.160 443 tcp4
+ remote 212.83.182.127 443 tcp4
+ remote 212.129.62.247 443 tcp4
+ reneg-sec 0
+ script-security 2
+ up-restart
+ '';
+ up = let dev = "ov-${ns}"; in ''
+ set -eux
+ PATH=${lib.makeBinPath [pkgs.iproute]}
+ ip link set dev "${dev}" up netns "${ns}" mtu "$tun_mtu"
+ ip netns exec "${ns}" ${pkgs.writeShellScript "route-up.sh" ''
+ set -eux
+ PATH=${lib.makeBinPath [pkgs.iproute pkgs.coreutils]}
+
+ ip link set dev lo up
+
+ mkdir -p /etc/netns/"${ns}"
+ foreign_opt_domains=
+ process_foreign_option () {
+ case "$1:$2" in
+ dhcp-option:DNS) echo "nameserver $3" >>/etc/netns/"${ns}"/resolv.conf ;;
+ dhcp-option:DOMAIN) foreign_opt_domains="$foreign_opt_domains $3" ;;
+ esac
+ }
+ if test ! -e /etc/netns/"${ns}"/resolv.conf; then
+ # add DNS settings if given in foreign options
+ i=1
+ while
+ eval opt=\"\''${foreign_option_$i-}\"
+ [ -n "$opt" ]
+ do
+ process_foreign_option $opt
+ i=$(( i + 1 ))
+ done
+ for d in $foreign_opt_domains; do
+ printf '%s\n' "domain $1" "search $*" \
+ >>/etc/netns/"${ns}"/resolv.conf
+ done
+ fi
+
+ netmask4="''${ifconfig_netmask:-30}"
+ netbits6="''${ifconfig_ipv6_netbits:-112}"
+ if [ -n "''${ifconfig_local-}" ]; then
+ if [ -n "''${ifconfig_remote-}" ]; then
+ ip -4 addr replace \
+ local "$ifconfig_local" \
+ peer "$ifconfig_remote/$netmask4" \
+ ''${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"} \
+ dev "${dev}"
+ else
+ ip -4 addr replace \
+ local "$ifconfig_local/$netmask4" \
+ ''${ifconfig_broadcast:+broadcast "$ifconfig_broadcast"} \
+ dev "${dev}"
+ fi
+ fi
+ if [ -n "''${ifconfig_ipv6_local-}" ]; then
+ if [ -n "''${ifconfig_ipv6_remote-}" ]; then
+ ip -6 addr replace \
+ local "$ifconfig_ipv6_local" \
+ peer "$ifconfig_ipv6_remote/$netbits6" \
+ dev "${dev}"
+ else
+ ip -6 addr replace \
+ local "$ifconfig_ipv6_local/$netbits6" \
+ dev "${dev}"
+ fi
+ fi
+
+ ${pkgs.writeScript "ruleset" openvpn.servers.${ns}.nftables}
+ ''}
+ '';
+ routeUp = ''
+ set -eux
+ PATH=${lib.makeBinPath [pkgs.iproute]}
+ ${pkgs.coreutils}/bin/env
+ ip netns exec "${ns}" ${pkgs.writeShellScript "route-up.sh" ''
+ set -eux
+ PATH=${lib.makeBinPath [pkgs.iproute]}
+ i=1
+ while
+ eval net=\"\''${route_network_$i-}\"
+ eval mask=\"\''${route_netmask_$i-}\"
+ eval gw=\"\''${route_gateway_$i-}\"
+ eval mtr=\"\''${route_metric_$i-}\"
+ [ -n "$net" ]
+ do
+ ip -4 route replace "$net/$mask" via "$gw" ''${mtr:+metric "$mtr"}
+ i=$(( i + 1 ))
+ done
+
+ if [ -n "''${route_vpn_gateway-}" ]; then
+ ip -4 route replace default via "$route_vpn_gateway"
+ fi
+
+ i=1
+ while
+ # There doesn't seem to be $route_ipv6_metric_<n>
+ # according to the manpage.
+ eval net=\"\''${route_ipv6_network_$i-}\"
+ eval gw=\"\''${route_ipv6_gateway_$i-}\"
+ [ -n "$net" ]
+ do
+ ip -6 route replace "$net" via "$gw" metric 100
+ i=$(( i + 1 ))
+ done
+
+ # There's no $route_vpn_gateway for IPv6. It's not
+ # documented if OpenVPN includes default route in
+ # $route_ipv6_*. Set default route to remote VPN
+ # endpoint address if there is one. Use higher metric
+ # than $route_ipv6_* routes to give preference to a
+ # possible default route in them.
+ if [ -n "''${ifconfig_ipv6_remote-}" ]; then
+ ip -6 route replace default \
+ via "$ifconfig_ipv6_remote" metric 200
+ fi
+ ''}
+ '';
+ nftables = lib.mkBefore ''
+ #!${pkgs.nftables}/bin/nft -f
+ flush ruleset
+ table inet filter {
+ include "${../../../../var/nftables/filter.txt}"
+ chain input {
+ type filter hook input priority filter
+ policy drop
+ iifname lo accept
+ jump check-tcp
+ ct state { established, related } accept
+ jump accept-connectivity-input
+ jump check-broadcast
+ ct state invalid drop
+ }
+ chain forward {
+ type filter hook forward priority filter
+ policy drop
+ jump accept-connectivity-forward
+ }
+ chain output {
+ type filter hook output priority filter
+ policy drop
+ oifname lo accept
+ ct state { related, established } accept
+ jump accept-connectivity-output
+ }
+ }
+ '';
+ };
+};
+}
--- /dev/null
+-----BEGIN CERTIFICATE-----
+MIIFjTCCA3WgAwIBAgIBATANBgkqhkiG9w0BAQ0FADBZMRgwFgYDVQQKDA9SaXNl
+dXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UE
+AwwXUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EwHhcNMTQwNDI4MDAwMDAwWhcNMjQw
+NDI4MDAwMDAwWjBZMRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsM
+Emh0dHBzOi8vcmlzZXVwLm5ldDEgMB4GA1UEAwwXUmlzZXVwIE5ldHdvcmtzIFJv
+b3QgQ0EwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC76J4ciMJ8Sg0m
+TP7DF2DT9zNe0Csk4myoMFC57rfJeqsAlJCv1XMzBmXrw8wq/9z7XHv6n/0sWU7a
+7cF2hLR33ktjwODlx7vorU39/lXLndo492ZBhXQtG1INMShyv+nlmzO6GT7ESfNE
+LliFitEzwIegpMqxCIHXFuobGSCWF4N0qLHkq/SYUMoOJ96O3hmPSl1kFDRMtWXY
+iw1SEKjUvpyDJpVs3NGxeLCaA7bAWhDY5s5Yb2fA1o8ICAqhowurowJpW7n5ZuLK
+5VNTlNy6nZpkjt1QycYvNycffyPOFm/Q/RKDlvnorJIrihPkyniV3YY5cGgP+Qkx
+HUOT0uLA6LHtzfiyaOqkXwc4b0ZcQD5Vbf6Prd20Ppt6ei0zazkUPwxld3hgyw58
+m/4UIjG3PInWTNf293GngK2Bnz8Qx9e/6TueMSAn/3JBLem56E0WtmbLVjvko+LF
+PM5xA+m0BmuSJtrD1MUCXMhqYTtiOvgLBlUm5zkNxALzG+cXB28k6XikXt6MRG7q
+hzIPG38zwkooM55yy5i1YfcIi5NjMH6A+t4IJxxwb67MSb6UFOwg5kFokdONZcwj
+shczHdG9gLKSBIvrKa03Nd3W2dF9hMbRu//STcQxOailDBQCnXXfAATj9pYzdY4k
+ha8VCAREGAKTDAex9oXf1yRuktES4QIDAQABo2AwXjAdBgNVHQ4EFgQUC4tdmLVu
+f9hwfK4AGliaet5KkcgwDgYDVR0PAQH/BAQDAgIEMAwGA1UdEwQFMAMBAf8wHwYD
+VR0jBBgwFoAUC4tdmLVuf9hwfK4AGliaet5KkcgwDQYJKoZIhvcNAQENBQADggIB
+AGzL+GRnYu99zFoy0bXJKOGCF5XUXP/3gIXPRDqQf5g7Cu/jYMID9dB3No4Zmf7v
+qHjiSXiS8jx1j/6/Luk6PpFbT7QYm4QLs1f4BlfZOti2KE8r7KRDPIecUsUXW6P/
+3GJAVYH/+7OjA39za9AieM7+H5BELGccGrM5wfl7JeEz8in+V2ZWDzHQO4hMkiTQ
+4ZckuaL201F68YpiItBNnJ9N5nHr1MRiGyApHmLXY/wvlrOpclh95qn+lG6/2jk7
+3AmihLOKYMlPwPakJg4PYczm3icFLgTpjV5sq2md9bRyAg3oPGfAuWHmKj2Ikqch
+Td5CHKGxEEWbGUWEMP0s1A/JHWiCbDigc4Cfxhy56CWG4q0tYtnc2GMw8OAUO6Wf
+Xu5pYKNkzKSEtT/MrNJt44tTZWbKV/Pi/N2Fx36my7TgTUj7g3xcE9eF4JV2H/sg
+tsK3pwE0FEqGnT4qMFbixQmc8bGyuakr23wjMvfO7eZUxBuWYR2SkcP26sozF9PF
+tGhbZHQVGZUTVPyvwahMUEhbPGVerOW0IYpxkm0x/eaWdTc4vPpf/rIlgbAjarnJ
+UN9SaWRlWKSdP4haujnzCoJbM7dU9bjvlGZNyXEekgeT0W2qFeGGp+yyUWw8tNsp
+0BuC1b7uW/bBn/xKm319wXVDvBgZgcktMolak39V7DVO
+-----END CERTIFICATE-----
--- /dev/null
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEAs4V9VZQSh1xSjk0tIUc3B6nEu8uLht/WDp+LU/RzPdjLDMXc
+irpRKzBAuhqJwWB0SBw8LoaNp1DnIVetEa1RmuWkD+VVTtDwaPwst36T64BHrKzP
+yiK/vXs5mzhm4KbLKFlcwOYGysNrORVrMJtSsK6TD9TpoPEeELTJt8gJ1mFGZBjY
+HHRMGvYOvZwFhtsMDNSj5b48KwxIIiiPfrkYElNRU35NQcZfT8ETvRCM+R98E+3E
+YFY017Lhfzdgak5LWttYB/AVruOMbmSv50WKT6rhZFeG6llelEcPaRb1aT6IR3uq
+nhQLn/xXsUKEO+pAvOUb6p+GyOwcQMMAHDLkOQIDAQABAoIBAB31hBIZEPKIBLr8
+xDBOiy97NHrGoDVU+4sbMwxCukyy9kfeaUy5hTw45ERqk1yzNRSnqZ92EwO+K6RT
+1m0hyIGaG0QP2Km7krNiii/hLtxZXxzBBjhMjkUX4Gg4BGsvSq4kI6eJe86wyB8R
+pP7KnQUhTSeSN58FPig5k4RZHNMqxwIjWLBWoz3qy82CtICcJLWDd0ro/rNZFW8h
+LAteXA7DuOlbyFHcC0SG8kctB9ZRPkasdwrF6swyBOTTtwabsMXfat8f+mqM6Efo
+VZ3Xp2wN0UXEFVjJXMEDDeQH+q0kGE7H6MQE/0FiOt98wLuC5bBYQC0HxMSlWdz1
+USbPDVUCgYEA4vlA29mvSffe4iqDC83VtawMt4lC5m2Zqs8+D4BV1kUnnA9OO1zu
+ZPmof4eWj6K17k7YXO8Xd8je794s4iTmZvO5Ig76bZk43N8aXSr0M+WmMMLRKAbC
+EsJlVOwwwwmu2sQLHBEeS+9vsnA1tlslvtqsq5/fEBOFXGMvMrS9be8CgYEAynq6
+hTKodj7BpvwipGXLa+uaPN8ttCesOUc+yKK9nuMnpJNPU1MCyTEtskijsz823Tzi
+ti1dyTQSiBFtFgh8D1dUYKdd98u3ljzoToSsaDvIyMvn/2pxvTGMvZ9VaMSRHlZI
+bMC9xtfchuDzVR3APh2I4CV9UHnCEiIVtRrd+FcCgYEA0wdWI1KI5Kf+ZZ+LCf2N
+toTJqheHyQCcADEBjZ4PsNHJWxLr9MuZpu5smG3zMYbhyjkqd3WhBzEO/kw+xN/0
+DEKMnbr5Yc81DD6un3Mha+MYGnv3xVRLOu/dEREs4Rnupd3iSm0sEwQCgRBNEEg8
+lu9v3X4eAi90LgrVxjo/aacCgYEAqCOeO/nDNt4KRbZethHqCKZPIHlcJJxFQhNN
+qaKqwAR16Q6C8vid+aCjB8eWWMUHtFRZF1s45FofgWqnIYLOMpccdF7Hg3xh6ZqO
+dpVp7eynYUciUlF8PdWlv9lOPX/t2jlgTx8G+NZMRJ0MtAPOnkY8YZYAKBHT/Obd
+C9VRumUCgYB5njH4P8PNeBA/H/vYF17a9F6ulDYHB5/BZnFcPfuxiov/aNepVyvt
+Z+QY6SmFdmak00YLh3qOGT5ek6iMODfKBe625VIr4p3akwzr/bu/LWHWNpfffaET
+bvJ4nzplqyYkMV9nLr+9N/iUjtRXQ0yHJp+cBRu2cS032TDyzplc7A==
+-----END RSA PRIVATE KEY-----
+-----BEGIN CERTIFICATE-----
+MIIEmzCCAoOgAwIBAgIQT9fuPod6b6yND5zUoXK38TANBgkqhkiG9w0BAQsFADB1
+MRgwFgYDVQQKDA9SaXNldXAgTmV0d29ya3MxGzAZBgNVBAsMEmh0dHBzOi8vcmlz
+ZXVwLm5ldDE8MDoGA1UEAwwzUmlzZXVwIE5ldHdvcmtzIFJvb3QgQ0EgKGNsaWVu
+dCBjZXJ0aWZpY2F0ZXMgb25seSEpMB4XDTIwMDgyMjAwMDAwMFoXDTIwMTEyMjAw
+MDAwMFowLTErMCkGA1UEAwwiVU5MSU1JVEVEODE5a3Rxa3ZhNGkyeDEzbW5wNnJ2
+MmswYzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALOFfVWUEodcUo5N
+LSFHNwepxLvLi4bf1g6fi1P0cz3YywzF3Iq6USswQLoaicFgdEgcPC6GjadQ5yFX
+rRGtUZrlpA/lVU7Q8Gj8LLd+k+uAR6ysz8oiv717OZs4ZuCmyyhZXMDmBsrDazkV
+azCbUrCukw/U6aDxHhC0ybfICdZhRmQY2Bx0TBr2Dr2cBYbbDAzUo+W+PCsMSCIo
+j365GBJTUVN+TUHGX0/BE70QjPkffBPtxGBWNNey4X83YGpOS1rbWAfwFa7jjG5k
+r+dFik+q4WRXhupZXpRHD2kW9Wk+iEd7qp4UC5/8V7FChDvqQLzlG+qfhsjsHEDD
+ABwy5DkCAwEAAaNvMG0wHQYDVR0OBBYEFCRYWXXaTEtq6EbvKXTDkTNTOf70MAsG
+A1UdDwQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAjAJBgNVHRMEAjAAMB8GA1Ud
+IwQYMBaAFBf0G9XlKgEBTWuiXTYKKQmWZYBGMA0GCSqGSIb3DQEBCwUAA4ICAQCV
+sL/zmlK0f8conYDz2d5uZ0qIcJjtsb1DtE3vHULrei0cVgFuAX/y7XT4ddzj64r6
+PzkoHSZ5FhVbg/ZN0olpEed25kt6bp4m2QvfRNd/qctcYmnqsSZdC5vb7NByBWQE
+a7by2zvG281W0J+PRrXcnbPB2dTUMw7/mEJ9MIh5KfHWoPQl+KKYJorOgkoUACMS
+L1k+0xxKGOE7DDwALGa/Uh8KSEZ2tF3OrYTNfweaOmdjn6UBzii1Jn54aU4dhwea
+I5WFWDQ3TxOdtSrOWHuyVLNGE61iwMAhqLmPlBl3tqci/BHe5/bAKWx4FkS6GcZ6
++i6mCqJG93rT+XLmePqFd9WQKd5Ff9kG104X3Fv5qnVRxR+eYRqZjDg6kySFyj3G
+ZM9SXYH0dMl3oxMjroIBlIKIW3A+VFjWpM2W49eib+wVL0YL5wMTCNpK7ZM84amz
+b1Q1A9jKgPMmbIL9HFWDjJigMBC6SYu3vfNUsXQzimrRvho6HBpQ63X3FcOOAlZ3
+5z/3OFWwwRvI/S7SENgRj7QB6mTc0z18BdwYKB7UZX8xhoZWYr9UaKeo/OGoSi1K
+LqEe6R30A8PYGYgnXxeOe0adZHiIIElE9ypZccy2qAcak1BYdoHjQqoY96Amqi37
+J24ftvwhm5GUwYFRecUP7Ll/NI6AjcgxxDxU5v2viA==
+-----END CERTIFICATE-----
inherit (config.services) transmission;
inherit (config.users) users;
inherit (config.security) gnupg;
+ netns = "riseup";
in
{
users.groups.transmission.members = [
users."julm".name
];
-networking.nftables.ruleset = ''
- add rule inet filter net2fw tcp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission"
- add rule inet filter net2fw udp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission"
- add rule inet filter fw2net meta skuid ${transmission.user} counter accept comment "Transmission"
+services.openvpn.servers.${netns}.nftables = ''
+ add rule inet filter input tcp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission"
+ add rule inet filter input udp dport ${toString transmission.settings.peer-port} counter accept comment "Transmission"
+ add rule inet filter output meta skuid ${transmission.user} counter accept comment "Transmission"
'';
#users.groups.keys.members = [ transmission.user ];
security.gnupg.secrets."transmission/settings.json" = {
user = transmission.user;
};
systemd.services.transmission = {
- after = [ gnupg.secrets."transmission/settings.json".service ];
- requires = [ gnupg.secrets."transmission/settings.json".service ];
+ after = [
+ gnupg.secrets."transmission/settings.json".service
+ "netns@${netns}.service"
+ ];
+ requires = [
+ gnupg.secrets."transmission/settings.json".service
+ "netns@${netns}.service"
+ ];
+ serviceConfig.NetworkNamespacePath = "/var/run/netns/${netns}";
};
services.transmission = {
enable = true;
queue-stalled-enabled = true;
queue-stalled-minutes = 30;
speed-limit-down-enabled = false;
- speed-limit-up = 500;
+ speed-limit-up = 50;
speed-limit-up-enabled = true;
alt-speed-enabled = true;
alt-speed-time-enabled = true;
- alt-speed-down = 5000;
- alt-speed-up = 50;
+ alt-speed-down = 1000;
+ alt-speed-up = 0;
alt-speed-time-day = 127; # all days. 65; # weekend only
alt-speed-time-begin = 360; # 06h00 local time
alt-speed-time-end = 1320; # 22h00 local time
enable = true;
ruleset = lib.mkBefore ''
table inet filter {
- set lograte4 { type ipv4_addr; size 65535; flags dynamic; }
- #set lograte6 { type ipv6_addr; size 65535; flags dynamic; }
- chain ping-flood {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: "
- #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: "
- counter drop
- }
- chain check-ping {
- ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- #ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
- }
- chain smurf {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: "
- #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: "
- counter drop
- }
- chain check-broadcast {
- #ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast"
- fib saddr type broadcast counter goto smurf
- ip saddr 224.0.0.0/4 counter goto smurf
- }
- chain bogus-tcp {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
- #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
- counter drop
- }
- chain syn-flood {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: "
- #add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: "
- counter drop
- }
- chain check-tcp {
- tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp
- tcp flags & (ack|fin) == fin counter goto bogus-tcp
- tcp flags & (ack|psh) == psh counter goto bogus-tcp
- tcp flags & (ack|urg) == urg counter goto bogus-tcp
- tcp flags & (fin|ack) == fin counter goto bogus-tcp
- tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp
- tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp
- tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan"
- tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan"
- tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan"
- tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan"
- tcp flags == (fin|urg|psh) counter goto bogus-tcp
- tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID"
- tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp
-
- ct state new tcp flags != syn counter goto bogus-tcp
- tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp
- tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood
- }
- chain spoofing {
- add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "spoofing: "
- counter drop
- }
- chain check-public {
- ip saddr 0.0.0.0/8 counter goto spoofing
- ip saddr 10.0.0.0/8 counter goto spoofing
- ip saddr 127.0.0.0/8 counter goto spoofing
- ip saddr 169.254.0.0/16 counter goto spoofing
- ip saddr 172.16.0.0/12 counter goto spoofing
- ip saddr 192.0.2.0/24 counter goto spoofing
- ip saddr 192.168.0.0/16 counter goto spoofing
- ip saddr 224.0.0.0/3 counter goto spoofing
- ip saddr 240.0.0.0/5 counter goto spoofing
- }
+ include "${../../../var/nftables/filter.txt}"
chain net2fw {
jump check-public
# Some .nix append rules here with: add rule inet filter net2fw ...
# accept traffic already established
ct state { established, related } accept
+ jump accept-connectivity-input
+ jump check-broadcast
ct state invalid drop
# admin services
tcp dport 22 counter accept comment "SSH"
udp dport 60000-61000 counter accept comment "Mosh"
- # ICMP
- ip protocol icmp icmp type echo-request counter accept
- ip protocol icmp icmp type destination-unreachable counter accept
- ip protocol icmp icmp type router-solicitation counter accept
- ip protocol icmp icmp type router-advertisement counter accept
- ip protocol icmp icmp type time-exceeded counter accept
- ip protocol icmp icmp type parameter-problem counter accept
- ip protocol icmp log level warn prefix "net2fw: icmpv: " counter accept
- #ip protocol icmp icmp type { echo-request, destination-unreachable, router-solicitation, router-advertisement, time-exceeded, parameter-problem } counter accept
-
- #ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-solicit counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type nd-neighbor-advert counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-solicit counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-query counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-report counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type mld-listener-reduction counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-solicit counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type ind-neighbor-advert counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type mld2-listener-report counter accept
- #ip6 nexthdr ipv6-icmp log level warn prefix "net2fw: icmpv6: " counter accept
- #ip6 nexthdr ipv6-icmp icmpv6 type { echo-request, nd-neighbor-solicit, nd-neighbor-advert, nd-router-solicit, nd-router-advert, mld-listener-query, mld-listener-report, mld-listener-reduction, destination-unreachable, packet-too-big, time-exceeded, parameter-problem, ind-neighbor-solicit, ind-neighbor-advert, mld2-listener-report } counter accept
-
- # ICMP
- ip protocol icmp icmp type echo-request accept
- #ip6 nexthdr ipv6-icmp icmpv6 type echo-request accept
-
# Some .nix append gotos here with: add rule inet filter input iffname ... goto ...
}
chain output {
oifname lo accept
ct state { established, related } accept
- ct state invalid drop
+ jump accept-connectivity-output
- icmp type echo-request counter accept comment "Ping"
tcp dport 22 counter accept comment "SSH"
# Some .nix append gotos here with: add rule inet filter output oifname ... goto ...
#modules/security/gnupg.nix
#modules/services/networking/biboumi.nix
#modules/services/networking/croc.nix
+ modules/services/networking/netns.nix
+ modules/services/networking/openvpn.nix
#/home/julm/src/nix/nixpkgs/.git-worktree/transmission/nixos/modules/services/torrent/transmission.nix
#/home/julm/src/nix/nixpkgs/nixos/modules/services/torrent/transmission.nix
#modules/services/mail/mlmmj.nix
#"security/gnupg.nix"
#"services/networking/biboumi.nix"
#"services/networking/croc.nix"
+ "services/networking/netns.nix"
+ "services/networking/openvpn.nix"
#"services/torrent/transmission.nix"
"services/freeciv.nix"
];
--- /dev/null
+{ pkgs, lib, config, ... }:
+{
+systemd.services."netns@" = {
+ description = "%I network namespace";
+ before = [ "network.target" ];
+ serviceConfig = {
+ Type = "oneshot";
+ RemainAfterExit = true;
+ PrivateNetwork = true;
+ ExecStart = "${pkgs.iproute}/bin/ip netns add %i";
+ ExecStop = "${pkgs.iproute}/bin/ip netns del %i";
+ };
+};
+}
--- /dev/null
+{ config, lib, pkgs, ... }:
+
+with lib;
+
+let
+
+ cfg = config.services.openvpn;
+
+ inherit (pkgs) openvpn;
+
+ makeOpenVPNJob = cfg: name:
+ let
+
+ path = makeBinPath (getAttr "openvpn-${name}" config.systemd.services).path;
+
+ upScript = ''
+ export PATH=${path}
+
+ # For convenience in client scripts, extract the remote domain
+ # name and name server.
+ for var in ''${!foreign_option_*}; do
+ x=(''${!var})
+ if [ "''${x[0]}" = dhcp-option ]; then
+ if [ "''${x[1]}" = DOMAIN ]; then domain="''${x[2]}"
+ elif [ "''${x[1]}" = DNS ]; then nameserver="''${x[2]}"
+ fi
+ fi
+ done
+
+ ${cfg.up}
+ ${optionalString cfg.updateResolvConf
+ "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"}
+ '';
+
+ downScript = ''
+ export PATH=${path}
+ ${optionalString cfg.updateResolvConf
+ "${pkgs.update-resolv-conf}/libexec/openvpn/update-resolv-conf"}
+ ${cfg.down}
+ '';
+
+ configFile = pkgs.writeText "openvpn-config-${name}"
+ ''
+ errors-to-stderr
+ ${optionalString (cfg.up != "" || cfg.down != "" || cfg.updateResolvConf) "script-security 2"}
+ ${cfg.config}
+ ${optionalString (cfg.up != "" || cfg.updateResolvConf)
+ "up ${pkgs.writeShellScript "openvpn-${name}-up" upScript}"}
+ ${optionalString (cfg.routeUp != "")
+ "route-up ${pkgs.writeShellScript "openvpn-${name}-up" cfg.routeUp}"}
+ ${optionalString (cfg.down != "" || cfg.updateResolvConf)
+ "down ${pkgs.writeShellScript "openvpn-${name}-down" downScript}"}
+ ${optionalString (cfg.authUserPass != null)
+ "auth-user-pass ${pkgs.writeText "openvpn-credentials-${name}" ''
+ ${cfg.authUserPass.username}
+ ${cfg.authUserPass.password}
+ ''}"}
+ '';
+
+ in {
+ description = "OpenVPN instance ‘${name}’";
+
+ wantedBy = optional cfg.autoStart "multi-user.target";
+ after = [ "network.target" ];
+
+ path = [ pkgs.iptables pkgs.iproute pkgs.nettools ];
+
+ serviceConfig.ExecStart = "@${openvpn}/sbin/openvpn openvpn --suppress-timestamps --config ${configFile}";
+ serviceConfig.Restart = "always";
+ serviceConfig.Type = "notify";
+ };
+
+in
+
+{
+ imports = [
+ (mkRemovedOptionModule [ "services" "openvpn" "enable" ] "")
+ ];
+
+ ###### interface
+
+ options = {
+
+ services.openvpn.servers = mkOption {
+ default = {};
+
+ example = literalExample ''
+ {
+ server = {
+ config = '''
+ # Simplest server configuration: https://community.openvpn.net/openvpn/wiki/StaticKeyMiniHowto
+ # server :
+ dev tun
+ ifconfig 10.8.0.1 10.8.0.2
+ secret /root/static.key
+ ''';
+ up = "ip route add ...";
+ down = "ip route del ...";
+ };
+
+ client = {
+ config = '''
+ client
+ remote vpn.example.org
+ dev tun
+ proto tcp-client
+ port 8080
+ ca /root/.vpn/ca.crt
+ cert /root/.vpn/alice.crt
+ key /root/.vpn/alice.key
+ ''';
+ up = "echo nameserver $nameserver | ''${pkgs.openresolv}/sbin/resolvconf -m 0 -a $dev";
+ down = "''${pkgs.openresolv}/sbin/resolvconf -d $dev";
+ };
+ }
+ '';
+
+ description = ''
+ Each attribute of this option defines a systemd service that
+ runs an OpenVPN instance. These can be OpenVPN servers or
+ clients. The name of each systemd service is
+ <literal>openvpn-<replaceable>name</replaceable>.service</literal>,
+ where <replaceable>name</replaceable> is the corresponding
+ attribute name.
+ '';
+
+ type = with types; attrsOf (submodule {
+
+ options = {
+
+ config = mkOption {
+ type = types.lines;
+ description = ''
+ Configuration of this OpenVPN instance. See
+ <citerefentry><refentrytitle>openvpn</refentrytitle><manvolnum>8</manvolnum></citerefentry>
+ for details.
+
+ To import an external config file, use the following definition:
+ <literal>config = "config /path/to/config.ovpn"</literal>
+ '';
+ };
+
+ up = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Shell commands executed when the instance is starting.
+ '';
+ };
+
+ routeUp = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ '';
+ };
+
+ down = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ Shell commands executed when the instance is shutting down.
+ '';
+ };
+
+ nftables = mkOption {
+ default = "";
+ type = types.lines;
+ description = ''
+ '';
+ };
+
+ autoStart = mkOption {
+ default = true;
+ type = types.bool;
+ description = "Whether this OpenVPN instance should be started automatically.";
+ };
+
+ updateResolvConf = mkOption {
+ default = false;
+ type = types.bool;
+ description = ''
+ Use the script from the update-resolv-conf package to automatically
+ update resolv.conf with the DNS information provided by openvpn. The
+ script will be run after the "up" commands and before the "down" commands.
+ '';
+ };
+
+ authUserPass = mkOption {
+ default = null;
+ description = ''
+ This option can be used to store the username / password credentials
+ with the "auth-user-pass" authentication method.
+
+ WARNING: Using this option will put the credentials WORLD-READABLE in the Nix store!
+ '';
+ type = types.nullOr (types.submodule {
+
+ options = {
+ username = mkOption {
+ description = "The username to store inside the credentials file.";
+ type = types.str;
+ };
+
+ password = mkOption {
+ description = "The password to store inside the credentials file.";
+ type = types.str;
+ };
+ };
+ });
+ };
+ };
+
+ });
+
+ };
+
+ };
+
+
+ ###### implementation
+
+ config = mkIf (cfg.servers != {}) {
+
+ systemd.services = listToAttrs (mapAttrsFlatten (name: value: nameValuePair "openvpn-${name}" (makeOpenVPNJob value name)) cfg.servers);
+
+ environment.systemPackages = [ openvpn ];
+
+ boot.kernelModules = [ "tun" ];
+
+ };
+
+}
--- /dev/null
+# A set containing the udp port(s) to which SSDP replies are allowed.
+set ssdp_out {
+ type inet_service
+ timeout 5s
+}
+set lograte4 { type ipv4_addr; size 65535; flags dynamic; }
+set lograte6 { type ipv6_addr; size 65535; flags dynamic; }
+chain block {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "block: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "block: "
+ counter drop
+}
+chain ping-flood {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "ping-flood: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "ping-flood: "
+ counter drop
+}
+chain smurf {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "smurf: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "smurf: "
+ counter drop
+}
+chain bogus-tcp {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "bogus-tcp: "
+ counter drop
+}
+chain syn-flood {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "syn-flood: "
+ add @lograte6 { ip6 saddr limit rate 1/minute } log level warn prefix "syn-flood: "
+ counter drop
+}
+chain check-tcp {
+ tcp flags syn tcp option maxseg size != 536-65535 counter goto bogus-tcp
+ tcp flags & (ack|fin) == fin counter goto bogus-tcp
+ tcp flags & (ack|psh) == psh counter goto bogus-tcp
+ tcp flags & (ack|urg) == urg counter goto bogus-tcp
+ tcp flags & (fin|ack) == fin counter goto bogus-tcp
+ tcp flags & (fin|rst) == (fin|rst) counter goto bogus-tcp
+ tcp flags & (fin|psh|ack) == (fin|psh) counter goto bogus-tcp
+ tcp flags & (syn|fin) == (syn|fin) counter goto bogus-tcp comment "SYN-FIN scan"
+ tcp flags & (syn|rst) == (syn|rst) counter goto bogus-tcp comment "SYN-RST scan"
+ tcp flags == (fin|syn|rst|psh|ack|urg) counter goto bogus-tcp comment "XMAS scan"
+ tcp flags == 0x0 counter goto bogus-tcp comment "NULL scan"
+ tcp flags == (fin|urg|psh) counter goto bogus-tcp
+ tcp flags == (fin|urg|psh|syn) counter goto bogus-tcp comment "NMAP-ID"
+ tcp flags == (fin|urg|syn|rst|ack) counter goto bogus-tcp
+
+ ct state new tcp flags != syn counter goto bogus-tcp
+ tcp sport 0 tcp flags & (fin|syn|rst|ack) == syn counter goto bogus-tcp
+ tcp flags & (fin|syn|rst|ack) == syn counter limit rate over 30/second burst 60 packets goto syn-flood
+}
+chain spoofing {
+ add @lograte4 { ip saddr limit rate 1/minute } log level warn prefix "spoofing: "
+ counter drop
+}
+chain check-broadcast {
+ #ip saddr 0.0.0.0/32 counter accept comment "DHCP broadcast"
+ fib saddr type broadcast counter goto smurf
+ #ip saddr 224.0.0.0/4 counter goto smurf
+}
+chain check-ping {
+ ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+}
+chain check-public {
+ ip saddr 0.0.0.0/8 counter goto spoofing
+ ip saddr 10.0.0.0/8 counter goto spoofing
+ ip saddr 127.0.0.0/8 counter goto spoofing
+ ip saddr 169.254.0.0/16 counter goto spoofing
+ ip saddr 172.16.0.0/12 counter goto spoofing
+ ip saddr 192.0.2.0/24 counter goto spoofing
+ ip saddr 192.168.0.0/16 counter goto spoofing
+ ip saddr 224.0.0.0/3 counter goto spoofing
+ ip saddr 240.0.0.0/5 counter goto spoofing
+}
+chain accept-icmpv6 {
+ # Traffic That Must Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.4.1
+ icmpv6 type destination-unreachable counter accept
+ icmpv6 type packet-too-big counter accept
+ icmpv6 type time-exceeded counter accept
+ icmpv6 type parameter-problem counter accept
+
+ # Address Configuration and Router Selection messages
+ # (must be received with hop limit = 255)
+ icmpv6 type nd-router-solicit ip6 hoplimit 255 counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type nd-router-advert ip6 hoplimit 255 counter accept
+ icmpv6 type nd-neighbor-solicit ip6 hoplimit 255 counter accept
+ icmpv6 type nd-neighbor-advert ip6 hoplimit 255 counter accept
+ icmpv6 type nd-redirect ip6 hoplimit 255 log level warn prefix "icmpv6: nd-redirect: " counter drop
+ icmpv6 type ind-neighbor-solicit ip6 hoplimit 255 counter accept
+ icmpv6 type ind-neighbor-advert ip6 hoplimit 255 counter accept
+
+ # Link-local multicast receiver notification messages
+ # (must have link-local source address)
+ icmpv6 type mld-listener-query ip6 saddr fe80::/10 counter accept
+ icmpv6 type mld-listener-report ip6 saddr fe80::/10 counter accept
+ icmpv6 type mld-listener-done ip6 saddr fe80::/10 counter accept
+ # https://tools.ietf.org/html/rfc3810 Multicast Listener Discovery Version 2 (MLDv2) for IPv6
+ icmpv6 type mld2-listener-report ip6 saddr fe80::/10 counter accept
+
+ # SEND Certificate Path notification messages
+ # (must be received with hop limit = 255)
+ icmpv6 type 148 ip6 hoplimit 255 counter accept comment "certificate-path-solicitation"
+ icmpv6 type 149 ip6 hoplimit 255 counter accept comment "certificate-path-advertisement"
+
+ # Multicast Router Discovery messages
+ # (must have link-local source address and hop limit = 1)
+ icmpv6 type 151 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-advertisement"
+ icmpv6 type 152 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-solicitation"
+ icmpv6 type 153 ip6 saddr fe80::/10 ip6 hoplimit 1 counter accept comment "multicast-router-termination"
+}
+chain accept-connectivity-input {
+ # Connectivity checking messages
+ # (multicast) ping
+ ip protocol icmp icmp type echo-reply counter accept
+
+ # drop packets with rh0 headers
+ rt type 0 jump block
+ rt type 0 jump block
+ rt type 0 jump block
+
+ # (multicast) ping
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+ #ct state invalid counter drop
+
+ ip protocol icmp icmp type destination-unreachable counter accept
+ ip protocol icmp icmp type time-exceeded counter accept
+ ip protocol icmp icmp type parameter-problem counter accept
+ ip protocol icmp icmp type echo-request limit rate over 10/second burst 20 packets goto ping-flood
+ ip protocol icmp icmp type echo-request counter accept
+ # echo-reply is handled before invalid packets to allow multicast ping
+ # which do not have an associated connection.
+
+ ip6 nexthdr ipv6-icmp jump accept-icmpv6
+
+ # Connectivity checking messages
+ icmpv6 type echo-request counter accept
+ # echo-reply is handled before invalid because of multicast
+}
+chain accept-connectivity-output {
+ ip protocol icmp counter accept
+ meta skuid 0 udp dport 33434-33523 counter accept comment "traceroute"
+
+ ip6 nexthdr ipv6-icmp jump accept-icmpv6
+
+ # Connectivity checking messages
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+}
+chain accept-connectivity-forward {
+ ip protocol icmp icmp type destination-unreachable counter accept
+ ip protocol icmp icmp type time-exceeded counter accept
+ ip protocol icmp icmp type parameter-problem counter accept
+ ip protocol icmp icmp type echo-request counter accept
+
+ # Traffic That Must Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.3.1
+ ip6 nexthdr ipv6-icmp icmpv6 type destination-unreachable counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type packet-too-big counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type time-exceeded counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type parameter-problem counter accept
+
+ # Connectivity checking messages
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-request counter accept
+ ip6 nexthdr ipv6-icmp icmpv6 type echo-reply counter accept
+
+ # Traffic That Normally Should Not Be Dropped
+ # https://tools.ietf.org/html/rfc4890#section-4.3.2
+ ip6 nexthdr ipv6-icmp icmpv6 type 144 counter accept comment "home-agent-address-discovery-request"
+ ip6 nexthdr ipv6-icmp icmpv6 type 145 counter accept comment "home-agent-address-discovery-reply"
+ ip6 nexthdr ipv6-icmp icmpv6 type 146 counter accept comment "mobile-prefix-solicitation"
+ ip6 nexthdr ipv6-icmp icmpv6 type 147 counter accept comment "mobile-prefix-advertisement"
+}