Reiwa's Linux router creation procedure ~ with raspi4 ~

Reiwa Linux router creation procedure

TL;DR You can make it for about 15,000 yen I was addicted to the Path MTU Discovery problem

flow

I usually do the following:

  1. OS installation
  2. PPPoE connection (connection to FLET'S network)
  3. Construction of DHCP and DNS
  4. Create a local network (bridge connection between wired and wireless)
  5. Configuration of iptables
  6. Make uPNP compatible

Necessary tools

must (about \ 14000)

may

OS installation

Procedure at the time of editing

Please read the X part of sdX as appropriate according to your environment.

#SD card format
fdisk /dev/sdx

Press o to delete partition
Press n to create partition
Press p and then 1 to create the primary partition
Press Enter without entering anything, specify the first sector,+128MB from the beginning 128MB to the first partition
Change the first partition to FAT32 by pressing t and then c
Press p and then 2 to create the primary partition
Press Enter without entering anything to specify the first sector, press Enter without entering anything, and make all the remaining area the second partition
Press w to write your changes

#Formatting and mounting partitions
mkfs.vfat /dev/sdx1
mkfs.ext4 /dev/sdx1
mkdir {boot,root}
mount /dev/sdx1 boot
mount /dev/sdx2 root

#OS installation
wget http://os.archlinuxarm.org/os/ArchLinuxARM-rpi-4-latest.tar.gz
bsdtar -xpf ArchLinuxARM-rpi-4-latest.tar.gz -C root
sync

#Move boot files to first partition
mv root/boot/* boot

#Remove the SD card and boot the OS
umount boot root

#OS initialization
##* RHEL's "subscription"-Because it is a command like "manager register"
##I feel that the nuances of initialization are different, but initialize at such times,populate
##Please comment if you know the appropriate Japanese translation
pacman-key --init
pacman-key --populate archlinuxarm

By default, less and vim are not included and it is too inconvenient to install.

pacman -S vim less

Connection to FLET'S network

When connecting ppp from Linux, you can easily connect using ppp.

ppp installation

pacman -S ppp

ppp settings

Create the configuration file in / etc / ppp / peers / . The settings are as follows. See pppd (8) for more details.

vim /etc/ppp/peers/hogehoge
plugin rp-pppoe.so

#Specify the interface on the WAN side. eth0 is the LAN port on the Raspi most of the time.
eth0

#List the connection ID specified by the provider.@<domain>Is also required.
name "[email protected]"

#Use the DNS server provided by your ISP
usepeerdns

#Always connect. Disconnect each time<demand>You can let it, but
#Since it is faster to turn off the power, there is no problem with persist in most cases.
persist 

#Automatically added to the routing table when a ppp connection is established
defaultroute

#Suppresses the output of the password in the log.
hide-password

#Do not require self-certification from your ISP. Basically it should be auth, but it seems to be noauth when dealing with ISP
noauth

#Enable IPV6 connection
+ipv6

The password for PPP connection is "/ etc / ppp / pap-secrets" or "/ etc / ppp / chap-secrets", and if the connection method is specified by the ISP, it is specified. Write the password on the method side.

It works fine if you write it on both, so if you don't understand it, you can write it on both.

# /etc/ppp/pap-secrets
<Value specified by name> * <Password specified by ISP>

(Example)
[email protected] * password

To check the connection, try manually starting the PPP connection.

pppd call /etc/ppp/peers/hogehoge

If working fine, ppp0 will be created.

ip a
...
ppp0:

Set the service to start automatically when the OS starts.

systemctl enable [email protected]

Creating a local network

Create a home network with systemd-networkd.

First, check the network interface that exists on the terminal.

ip a

You should get the following output.

lo:
eth0:
enp1s0u1:
wlan0:
ppp0:

Since it is convenient to have wireless and wired communication (Bonjour, etc.), I will create a bridge adapter and connect the wired network interface and the wireless network interface virtually with the L2 network.

Creating a bridge adapter

Create the following files to create the bridge adapter.

# /etc/systemd/network/br0.netdev
[NetDev]
Name=br0
Kind=bridge

After creating the file, restart systemd-netwokrd.

systemctl restart systemd-networkd

When you view the list of network interfaces again, the network device is created.

Since it is Reiwa, there is no need to do brctl or other troublesome things.

ip a
lo:
...
br0: (← increase)

Next, connect the device for your local network to the bridge. Since eth0 is used for PPP connection, it will not be changed.

# /etc/systemd/network/enp1s0u1.network (Create New)
[Match]
Name=enp1s0u1

[Network]
Bridge=br0

# /etc/systemd/network/wlan0.network (Create New)
[Match]
Name=wlan0

[Network]
Bridge=br0

The network interface is now connected to the bridge.

It's easy because it's Reiwa.

Next, specify the IP address statically so that it can be recognized on the local network. This time I set it to 192.168.0.1/24, but any address specified as a local address (https://tools.ietf.org/html/rfc1918) will do.

From the conclusion, it is the following address.

# /etc/systemd/network/br0.network (Create New)
[Match]
Name=br0

[Network]
Address=192.168.0.1/24
Gateway=192.168.0.1

After completing the settings, restart systemd-networkd again.

systemctl restart systemd-networkd

As shown below, br0 starts as 192.168.0.1, and enp1s0u1 and wlan0 are connected by L2, so they do not have an IP address. (The MAC address etc. will differ depending on the environment, so please read as appropriate.)

enp1s0u2: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether 04:ab:18:3c:d4:6b brd ff:ff:ff:ff:ff:ff
br0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether ae:52:e3:c8:67:ca brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.1/24 brd 192.168.0.255 scope global br0
       valid_lft forever preferred_lft forever
wlan0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel master br0 state UP group default qlen 1000
    link/ether dc:a6:32:71:0b:9e brd ff:ff:ff:ff:ff:ff

DHCP, DNS construction

The local network is created by the procedure so far, and if you manually enter the address of 192.168.0.0/24, it will work normally, but it is too troublesome to do it one by one. Therefore, build a DHCP and DNS server.

DHCP server construction

Install dhcpd.

pacman -S dhcpd

The dhcpd configuration file is "/etc/dhcpd.conf". Create a configuration file as shown below.

option domain-name-servers 192.168.0.1;
option subnet-mask 255.255.255.0;
option routers 192.168.0.1;

subnet 192.168.0.0 netmask 255.255.255.0 {
  range 192.168.0.10 192.168.0.200;
}

By making this setting, the following settings will be automatically made on the local network.

Setting value
IP address 192.168.0.10〜192.168.0.200 free IPs
default gateway 192.168.0.1
sub-net mask 255.255.255.0
DNS server 192.168.0.1

After creation, start the DHCP server and enable automatic startup.

systemctl enable dhcpd4
systemctl start dhcpd4

The above set can be the same with the following line. (Jabashi)

systemctl enable --now dhcpd4

Creating a DNS server

It does not resolve the name of the local PC, but creates a DNS cache server that only holds the DNS information of the Internet.

First, install bind.

pacman -S bind 

The configuration file is "/etc/named.conf". The settings when building as a DNS cache server are as follows.

options {
    //Directory to generate various files
    directory "/var/named";

    //PID file path
    pid-file "/run/named/named.pid";  

    //Network waiting for DNS queries
    listen-on { 127.0.0.1; 192.168.0.0/24; };

    //Network that responds to DNS queries
    allow-recursion { 127.0.0.1; 192.168.0.0/24; };

    //Networks that allow DNS zone transfers
    allow-transfer { none; };
    //Network that allows rewriting of DNS zone information
    allow-update { none; };

    //Resolve names only from forwarders
    forward only;
    //Parent DNS used by this DNS server(8.8.8.8,8.8.4.4 is google DNS)
    forwarders{ 8.8.8.8; 8.8.4.4; };

    //Hide server information
    version none;
    hostname none;
    server-id none;
};

After completing the settings, start bind with the following command and enable automatic startup.

systemctl enable named
systemctl start named

iptables configuration

As you may know if you have tried it so far, you can connect to the Internet from Raspi, but you cannot connect to the Internet from your local network at this time. Allows you to exit the ppp0 network from your local network.

First, allow IP forwarding because it is disabled in the OS.

cat /proc/sys/net/ipv4/ip_forward
0(Invalid)
# /etc/sysctl.d/ipforward.conf (Create New)
net.ipv4.ip_forward=1
net.ipv6.conf.default.forwarding=1
net.ipv6.conf.all.forwarding=1

After creating the settings, reboot the OS.

If you check again, IP forwarding should be enabled.

cat /proc/sys/net/ipv4/ip_forward
1

Then install iptables.

pacman -S iptables

Originally, you should add them one by one with the iptables command, but edit "/etc/iptables/iptables.rule" as follows.

*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
:MINIUPNPD - [0:0]
-A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ppp0 -j TCPMSS --clamp-mss-to-pmtu
COMMIT
*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT ACCEPT [0:0]
:TCP - [0:0]
:UDP - [0:0]
-A INPUT -i br0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i br0 -p tcp -m tcp --dport 53 -j ACCEPT
-A INPUT -i br0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i br0 -p tcp -m tcp --dport 67 -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP
-A INPUT -m conntrack --ctstate INVALID -j DROP
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable
-A INPUT -p tcp -j REJECT --reject-with tcp-reset
-A INPUT -j REJECT --reject-with icmp-proto-unreachable
-A FORWARD -i br0 -j ACCEPT
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT
-A FORWARD -j REJECT --reject-with icmp-host-unreachable
-A OUTPUT -o ppp0 -d 192.168.0.0/24 -j DROP
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
COMMIT
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A POSTROUTING -o ppp0 -j MASQUERADE
COMMIT

The meanings of the individual settings are as follows.

#It is a table of settings related to the network quality of the IP network called the ToS field called the mangle table.
*mangle
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

#Take action on the Path MTU Discovery problem.
#In Qiita, stackoverflow, etc., the packet size sent at one time is"""why"""Because it is set large
#With the default value of 1500, the packet size will be larger than expected by the network, and data will be lost in the middle.
#It will be destroyed. Set the packet size of MSS packet to the remote side with the following settings
#Enables the tell function to prevent unreceived packets from being sent.

-A POSTROUTING -p tcp --tcp-flags SYN,RST SYN -o ppp0 -j TCPMSS --clamp-mss-to-pmtu
#This table is used to deny connection permission.
*filter

#Deny packets from outside that do not fall into any rule
:INPUT DROP [0:0]

#Deny packets that go through a server that doesn't fall into any of the rules
:FORWARD DROP [0:0]

#Packets coming out of raspi to another network are allowed.
:OUTPUT ACCEPT [0:0]

# TCP/This is a table created for UDP.
:TCP - [0:0]
:UDP - [0:0]

#Local network(br0)Allow DNS queries from.
-A INPUT -i br0 -p udp -m udp --dport 53 -j ACCEPT
-A INPUT -i br0 -p tcp -m tcp --dport 53 -j ACCEPT

#Local network(br0)Allows DHCP queries from.
-A INPUT -i br0 -p udp -m udp --dport 67 -j ACCEPT
-A INPUT -i br0 -p tcp -m tcp --dport 67 -j ACCEPT

#Allows all communication of raspi itself.
-A INPUT -i lo -j ACCEPT

#Allow connections that have already been established in some way.
-A INPUT -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#Allows ICMP echoes.
-A INPUT -p icmp -m icmp --icmp-type 8 -m conntrack --ctstate NEW -j ACCEPT

#Transfers UDP connections to UDP table processing
-A INPUT -p udp -m conntrack --ctstate NEW -j UDP

#Transfer TCP connection to TCP table processing
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -m conntrack --ctstate NEW -j TCP

#Drops connections of unknown status.
-A INPUT -m conntrack --ctstate INVALID -j DROP

#Packets that do not match the UDP table are rejected with an error that the host does not exist.
-A INPUT -p udp -j REJECT --reject-with icmp-port-unreachable

#Packets that do not match the TCP table are rejected by TCP RESET.
-A INPUT -p tcp -j REJECT --reject-with tcp-reset

#Reject other connections with an error that does not have a corresponding protocol.
-A INPUT -j REJECT --reject-with icmp-proto-unreachable

#Allows communication from the local network to the Internet.
-A FORWARD -i br0 -j ACCEPT

#Allows sessions established from the local network side to pass through the server.
-A FORWARD -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT

#Reject communication that is neither of the top two.
-A FORWARD -j REJECT --reject-with icmp-host-unreachable

# 192.168.0.0/Blocks communications for 24 from going out to the Internet.
-A OUTPUT -o ppp0 -d 192.168.0.0/24 -j DROP

#Allow SSH connection.
-A TCP -p tcp -m tcp --dport 22 -j ACCEPT
#This is the table when the local network goes out to the Internet
*nat
:PREROUTING ACCEPT [0:0]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]

#Communication from the local network to the Internet is dynamically assigned and communicated by iptables.
#When set to SNAT, a constant value is always used.
-A POSTROUTING -o ppp0 -j MASQUERADE

After completing the settings, start iptables with the following command and enable automatic startup.

systemctl enable iptables
systemctl restart iptables

Make uPNP compatible

Since it is Reiwa, there are times when I want network devices to dynamically open ports with uPNP. Therefore, install miniupnpd so that the router can dynamically open ports in response to requests from the local network.

pacman -S miniupnpd

The configuration file is "/etc/miniupnpd/miniupnpd.conf".

#Specifies the outer interface
ext_ifname=ppp0

#Specifies the inner interface
listening_ip=br0

#Socket file(File for internal communication)Specify the location of.
minissdpdsocket=/var/run/minissdpd.sock

secure_mode=no
system_uptime=yes
notify_interval=60
clean_ruleset_interval=600
uuid=00000000-0000-0000-0000-000000000000

#Specifies the network that allows upnp
allow 1024-65535 192.168.0.0/24 1024-65535
deny 0-65535 0.0.0.0/0 0-65535

After completing the settings, start miniupnpd with the following command and enable automatic startup.

systemctl enable miniupnpd
systemctl restart miniupnpd

Recommended Posts

Reiwa's Linux router creation procedure ~ with raspi4 ~
Linux mint installation procedure
NAT router on Linux
manylinux1 wheelhouse creation procedure
linux with termux app
Linux SVN repository creation
LiveUSB creation on Linux