Współczesne komputery rzadko kiedy pracują w całkowitej izolacji od innych urządzeń tego typu. Nadzorujące ich pracę systemy operacyjne są przygotowane do zapewnienia komunikacji sieciowej między tymi urządzeniami, jeśli tylko zostały one wyposażone w modemy, adaptery sieciowe typu Ethernet, Wi-Fi, Bluetooth, itp., a jądro dysponuje odpowiednimi modułami obsługi tych urządzeń.
Od wielu już lat jądro systemu Linux wspiera komunikację sieciową w ramach protokołów IPv4 i IPv6, ale od kilku lat obsługa IPv6 jest domyślnie włączona, co – dzięki dostępnej w ramach tego protokołu autokonfiguracji – pozwala na natychmiastową komunikację hostów w ramach lokalnej sieci komputerowej (wykorzystywane są do tego specjalne adresy łącza lokalnego).
W ostatnich latach nastąpiło także ujednolicenie sposobu konfiguracji interfejsów,
niezależnie od używanej dystrybucji Linuksa. Stało się to dzięki zastosowaniu do tego celu
NetworkManagera, który nie tylko pozwala na łatwą konfigurację interfejsów ethernetowych,
ale także dobrze radzi sobie z konfiguracją interfejsów innych sieci (DSL, Wi-Fi,
szerokopasmowych sieci bezprzewodowych, InfiniBand). Ogromnym ułatwieniem w konfiguracji
sieci są dostępne w większości dystrybucji graficzne interfejsy do programu
NetworkManager, ale administrator systemu komputerowego nie może na nich polegać i z nich
korzystać, bo zwykle serwery nie pracują w trybie graficznym. Dlatego poniżej
konfigurowanie interfejsów i sieci jest realizowane przy wykorzystaniu komend nmcli
oraz ip
(zamiast ip
można korzystać z ifconfig
, ale ta komenda jest uznawana
za przestarzałą; jesteśmy na nią skazani konfigurując sieć w starszych wersjach systemu
operacyjnego). We wcześniejszych wersjach dystrybucji, takich jak Red Hat, CentOS, Fedora
i podobnych, do zarządzania interfejsami był używany skrypt /etc/rc.d/init/network.
Zob. Podstawowe informacje o protokołach IPv4 i IPv6 można znaleźć w notatkach do wykładu: Sieci komputerowe.
systemd używa domyślnie następującego schematu przydzielania nazw interfejsom sieciowym (przy założeniu, że obsługa podsystemu biosdevname jest wyłączona, tj. biosdevname=0; biosdevname jest pomocniczym programem użytkowym dla udev, opracowanym przez firmę Dell (na licencji GPL), który dostarcza spójnego mechanizmu nadawania nazw urządzeniom sieciowym na podstawie ich fizycznego położenia udostępnianego przez BIOS):
nazwy urobione wg informacji pozyskanych z oprogramowania firmowego lub BIOS-u (np. eno1); w przeciwnym razie nazwy wg schematu 2
nazwy urobione wg informacji pozyskanych z oprogramowania firmowego lub BIOS-u o położeniu urządzenia na szynie PCI (np. ens1); w przeciwnym razie nazwy wg schematu 3
nazwy urobione wg informacji o fizycznym położeniu NIC na płycie głównej (np. enp2s0); w przeciwnym razie nazwy wg schematu 5
nazwy urobione wg adresu MAC (np. enx78e7d1ea46da) nie sa stosowane, ale są dostępne na życzenie użytkownika
tradycyjny, nieprzewidywalny schemat nazewniczy, jeśli inne zawiodły (np. eth0)
Nazwy interfejsów sieciowych są zależne od ich typu i poprzedzone prefiksami:
en – Ethernet
wl – wireless LAN (WLAN)
ww – wireless wide area network (WWAN)
Pozostała część nazwy zależy od typu urządzenia:
Format |
Description |
---|---|
o<index> |
on-board device index number |
s<slot>[f<function>][d<dev_id>] |
hotplug slot index number |
x<MAC> |
MAC address |
p<bus>s<slot>[f<function>][d<dev_id>] |
PCI geographical location |
p<bus>s<slot>[f<function>][u<port>] [..][c<config>][i<interface>] |
USB port number chain |
Kilka przykładów wyznaczania nazw:
System |
device |
biosdevname -i device |
lspci |
---|---|---|---|
Dell |
em1 |
em1 |
|
Dell |
p2p1 |
p2p1 |
|
Supermicro |
eno1 |
em1 |
|
SunFire X4200 |
enp134s1f0 |
em1 |
86:01.0 … Gigabit … |
SunFire X4200 |
enp134s1f1 |
em2 |
86:01.1 … Gigabit … |
SunFire X4200 |
enp132s0 |
p1p1 |
84:00.0 … 10-Gigabit … |
SunFire X4440 |
enp3s0 |
p1p1 |
03:00.0 … 10-Gigabit … |
Nazwy wg biosdevname (schemat stosowany domyślnie dla systemów firmy Dell oraz gdy biosdevname został explicite włączony):
Urządzenie |
Stara nazwa |
Nowa nazwa |
Przykład |
---|---|---|---|
Embedded NIC |
eth[0123…] |
em[1234…] |
|
PCI NIC |
eth[0123…] |
p<slot>p<ethernet port> |
p2p1, p2p2 |
Jeśli nie chcemy modyfikować konfiguracji udev w celu zmiany nazwy interfejsu sieciowego,
to można tę nazwę zmienić korzystając z komendy ip
, np.:
# ip link set eth1 down
# ip link set eth1 name em2
# ip link set em2 up
Tę samą zmianę nazwy interfejsu sieciowego, ale w sposób trwały można uzyskać poprzez zastosowanie następujących komend:
# echo 'ACTION=="add", SUBSYSTEM=="net", DRIVERS=="?*", ATTR{address}=="54:52:00:10:00:02", NAME="em2"' \
> /etc/udev/rules.d/70-persistent-net.rules
# (modprobe -r virtio_net; modprobe virtio_net)&
Oczywiście w powyższym przykładzie adres MAC trzeba zastąpić adresem właściwym dla interfejsu, którego nazwę zmieniamy. Także nazwę modułu do obsługi danego rodzaju interfesju, który trzeba wyładować i ponownie załadować, należy dostosować do systemu komputerowego (np. interfejsy gigabitowe firmy Intel będą obsługiwane przez moduł e1000).
Każda z maszyn wirtualnych dysponuje dwoma adapterami ethernetowymi; zob. lspci
. Przy
pomocy komendy lspci można także określić moduł używany przez jądro do obsługi konkretnego
urządzenia:
[root@centos7-2 ~]# lspci -v -s 00:03.0
00:03.0 Ethernet controller: Red Hat, Inc Virtio network device
Subsystem: Red Hat, Inc Device 0001
Physical Slot: 3
Flags: bus master, fast devsel, latency 0, IRQ 10
I/O ports at c0a0 [size=32]
Memory at febf1000 (32-bit, non-prefetchable) [size=4K]
Expansion ROM at febd0000 [disabled] [size=64K]
Capabilities: [40] MSI-X: Enable+ Count=3 Masked-
Kernel driver in use: virtio-pci
Kernel modules: virtio_pci
Komenda lsmod | grep virtio_pci
potwierdza obecność wskazanego modułu w jądrze.
Komendy ifconfig
(w nowszych wersjach systemu już jej nie ma) oraz ip
pokazują
dostępne w systemie interfejsy sieciowe i ich konfigurację:
# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
inet 192.168.142.2 netmask 255.255.255.0 broadcast 192.168.142.255
inet6 fe80::5652:ff:fe01:2 prefixlen 64 scopeid 0x20<link>
ether 54:52:00:01:00:02 txqueuelen 1000 (Ethernet)
RX packets 74615 bytes 26271654 (25.0 MiB)
RX errors 0 dropped 9 overruns 0 frame 0
TX packets 6380 bytes 642702 (627.6 KiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
eth1: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
ether 54:52:00:10:00:02 txqueuelen 1000 (Ethernet)
RX packets 66956 bytes 3481944 (3.3 MiB)
RX errors 0 dropped 41857 overruns 0 frame 0
TX packets 14321 bytes 2540790 (2.4 MiB)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536
inet 127.0.0.1 netmask 255.0.0.0
inet6 ::1 prefixlen 128 scopeid 0x10<host>
loop txqueuelen 0 (Local Loopback)
RX packets 0 bytes 0 (0.0 B)
RX errors 0 dropped 0 overruns 0 frame 0
TX packets 0 bytes 0 (0.0 B)
TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
# ip address show
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN
link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
inet 127.0.0.1/8 scope host lo
valid_lft forever preferred_lft forever
inet6 ::1/128 scope host
valid_lft forever preferred_lft forever
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 54:52:00:01:00:02 brd ff:ff:ff:ff:ff:ff
inet 192.168.142.2/24 brd 192.168.142.255 scope global dynamic eth0
valid_lft 2369sec preferred_lft 2369sec
inet6 fe80::5652:ff:fe01:2/64 scope link
valid_lft forever preferred_lft forever
3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
link/ether 54:52:00:10:00:02 brd ff:ff:ff:ff:ff:ff
Wykorzystując interfejs eth1 można połączyć ze sobą maszyny wirtualne w odrębną, wydzieloną sieć (sieci). W tym celu trzeba wykonać następujące czynności:
sprawdzić, czy interfejs eth1 jest prawidłowo podłączony do urządzenia sieciowego (przełącznika)
# ethtool eth1
Settings for eth1:
Link detected: yes
przypisać interfejsowi statyczny adres z puli 10.0.0.0/24:
# ip address add 10.0.0.1/24 dev eth1
Przypisanie adresu do interfejsu wg powyższego przepisu jest równoznaczne z wykonaniem
komendy ip link set dev eth1 up
. Jak wygląda stan interfejsu i tablica routing po
wykonaniu komendy ip link set dev eth1 down
?
sprawdzić, czy host widzi bramę sieci oraz inne hosty w tej samej sieci
# ping -c 1 10.0.0.254
PING 10.0.0.254 (10.0.0.254) 56(84) bytes of data.
64 bytes from 10.0.0.254: icmp_seq=1 ttl=64 time=0.103 ms
--- 10.0.0.254 ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.103/0.103/0.103/0.000 ms
sprawdzić tablicę routingu
# ip route [show]
default via 192.168.142.254 dev eth0 proto static metric 100
10.0.0.0/24 dev eth1 proto kernel scope link src 10.0.0.1
192.168.142.0/24 dev eth0 proto kernel scope link src 192.168.142.1 metric 100
Zob. Przykłady użycia komendy ip.
W najnowszych wersjach systemu operacyjnego Linux (niezależnie od używanej dystrybucji) za
obsługę sieci jest odpowiedzialna oddzielna usługa systemowa o nazwie NetworkManager. Do
zarządzania tą usługą służy komenda nmcli
:
# nmcli con show [--active]
NAME UUID TYPE DEVICE
System eth0 5fb06bd0-0bb0-7ffb-45f1-d6edd65f3e03 802-3-ethernet eth0
Wired connection 1 bc674f80-f9b7-3850-bb79-df4207e13099 802-3-ethernet eth1
Przy jej pomocy można skonfigurować interfejs eth1 w następujący sposób:
# nmcli con delete [UUID] bc674f80-f9b7-3850-bb79-df4207e13099
Connection 'Wired connection 1' (bc674f80-f9b7-3850-bb79-df4207e13099) successfully deleted.
# cd /etc/sysconfig/network-scripts
# cat <<EOF > ifcfg-eth1
DEVICE=eth1
BOOTPROTO=none
ONBOOT=yes
IPADDR=10.111.0.1
PREFIX=24
DEFROUTE=no
DOMAIN="fizyka.umk.pl"
EOF
# nmcli con load /etc/sysconfig/network-scripts/ifcfg-eth1
Interfejs może być wyłączany/włączany przy pomocy komendy ifdown|ifup eth1
, ale lepiej
użyć komendy nmcli con down|up id 'System eth1'
lub nmcli con down|up UUID
, gdzie
UUID jest identyfikatorem połączenia, które wyświetla komenda nmcli con
.
Prosta modyfikacja pliku ifcfg-eth1 pozwala na przypisanie do interfejsu więcej niż jednego adresu, np.
# cat <<EOF > ifcfg-eth1
DEVICE=eth1
BOOTPROTO=static
ONBOOT=yes
IPADDR1=10.111.0.1
PREFIX1=24
IPADDR2=192.168.242.1
PREFIX2=24
DEFROUTE=no
EOF
# nmcli con load /etc/sysconfig/network-scripts/ifcfg-eth1
Opis wszystkich możliwych zmiennych, które mogą pojawić się w plikach konfigurujących interfejsy znajduje się w pliku /usr/share/doc/initscripts-9.49.37/sysconfig.txt.
Jeśli w sieci działa serwer DHCP, to interfejs eth1 można skonfigurować przy pomocy komendy:
# nmcli connection add type ethernet con-name 'System eth1 via dhcp' ifname eth1
W wyniku działania tej komendy powstaje plik ifcfg-System_eth1_via_dhcp o następującej zawartości:
# cat ifcfg-System_eth1_via_dhcp
TYPE=Ethernet
BOOTPROTO=dhcp
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
IPV6_ADDR_GEN_MODE=stable-privacy
NAME="System eth1 via dhcp"
UUID=e46f6d9f-b6dd-4ccc-af0f-b267e6b4b57e
DEVICE=eth1
ONBOOT=yes
Zob. Konfiguracja interfejsów w IPv6.
Firma Hurricane Electric (https://he.net/) pozwala na utworzenie (bez opłat) do pięciu tuneli pozwalających na dostęp do sieci IPv6.
Załóżmy, że został utworzony następujacy tunel:
IPv6 Tunnel Endpoints
Server IPv4 Address:216.66.80.162
Server IPv6 Address:2001:470:70:130::1/64
Client IPv4 Address:158.75.5.233
Client IPv6 Address:2001:470:70:130::2/64
Routed IPv6 Prefixes
Routed /64:2001:470:71:130::/64
Routed /48:2001:470:60be::/48
W celu skorzystania z tego tunelu należy na serwerze (158.75.5.233) wykonać następujące komendy:
ip tunnel add he-ipv6 mode sit remote $remoteIP local $localIP
ip link set he-ipv6 up
ip addr add $localIPv6 dev he-ipv6
ip route add ::/0 dev he-ipv6
sysctl net.ipv4.conf.he-ipv6.route_localnet=1
sysctl net.ipv6.conf.all.forwarding=1
gdzie $remoteIP (216.66.80.162) wskazuje na koniec tunelu po stronie HE, a $localIP (158.75.5.233) - po stronie klienta.
Pierwsza z komend tworzy tunel, druga go aktywuje, a trzecia przypisuje adres IPv6 po stronie klienta, tj. $localIPv6 (2001:470:70:130::2/64). Trzeba także powiadomić jądro, żeby serwer mógł działać jako router IPv6.
W tym celu trzeba dodatkowo przygotować plik konfiguracyjny dla usługi radvd.service:
interface $device
{
AdvSendAdvert on;
MinRtrAdvInterval 30;
MaxRtrAdvInterval 100;
prefix 2001:470:71:130::/64
{
AdvOnLink on;
AdvAutonomous on;
AdvRouterAddr off;
AdvValidLifetime 300;
AdvPreferredLifetime 30;
};
};
A następnie uruchomić usługę radvd rozgłaszającą zdefiniowane prefiksy sieci IPv6
(router advertisement daemon for IPv6): systemct start radvd
.
Komunikację w ramach sieci IPv6 można sprawdzić przy pomocy komendy ping6:
# ping6 -c5 www.ipv6tf.org
# ping6 -c5 e2867.dsca.akamaiedge.net
# ping6 -c5 ipv6.google.com