The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

Ubuntu 20.04 LTS 伺服器如何調整網路介面設定從 DHCP 變更為固定 IP 地址

Ubuntu 20.04 LTS 伺服器預設採用 Netplan 作為網路設定的工具,但是要變更網路介面設定實在是有點麻煩,沒找到有好用的 TUI (Terminal UI) 工具可以用。我想透過這篇文章記錄一下變更 IP 設定的過程。如果有不同的網路情境導致設定步驟不同,我會陸續補充到這篇文章裡。

從 DHCP 取得動態 IP 地址變更為固定 IP 地址

  1. 先透過 ip add show (ip a) 取得當前 IP 地址

    你可以從下方的 eth0 看到一個 dynamic 字眼,這代表這個 eth0 介面是從 DHCP 伺服器取得 IP 地址:

    1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
        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 mq state UP group default qlen 1000
        link/ether 00:16:2d:02:0a:32 brd ff:ff:ff:ff:ff:ff
        inet 192.168.1.11/24 brd 192.168.1.255 scope global dynamic eth0
          valid_lft 83597sec preferred_lft 83597sec
        inet6 fe80::215:5dff:fe01:a32/64 scope link
          valid_lft forever preferred_lft forever
    
  2. 你可以用以下命令擷取當前的網路資訊:

    sudo apt install net-tools -y
    
    # 如果 VM 只有一張網路介面可以這樣取得網路介面名稱 (eth0)
    NetworkInterface=$(ifconfig | grep 'flags' | cut -d ':' -f 1 | grep -v 'lo')
    
    # 取得當前 IP
    CurrentIP=$(ip a | grep inet | grep $NetworkInterface | sed -e 's/^[[:space:]]*//' | cut -d ' ' -f 2 | cut -d '/' -f 1)
    # 取得當前 Netmask
    CurrentNM=$(ip a | grep inet | grep $NetworkInterface | sed -e 's/^[[:space:]]*//' | cut -d ' ' -f 2 | cut -d '/' -f 2)
    # 取得當前 Gateway
    CurrentGW=$(ip r | grep 'default' | sed -e 's/^.* via //' | cut -d ' ' -f 1)
    # 取得當前 DNS 資訊 (systemd-resolve --status | grep -B 9 -A 6 "Current DNS Server")
    CurrentDNS=$(systemd-resolve --status | grep -A 6 "Current DNS Server" | sed 1d | sed -e 's/^[[:space:]]*//' | sed -e 's/[[:space:]]*$//' | sed -e 's/^DNS Servers: //' | tr '\n' ',' | sed -e 's/,$//')
    

    我這裡用了許多 Linux 常見工具(grep, sed, cut, tr)的操作技巧,細節請自行查閱 man page 說明。

  3. 直接拿現有的網路介面設定轉換成固定 IP 的設定值,並直接套用更新

    當你透過 subiquity (Ubuntu Server Installer) 安裝 OS 的過程,如果是透過 DHCP 伺服器取得 IP 的話,預設 cloud-init 可能會用來管理伺服器的 IP 設定,我們要先確認目前主機沒有透過 cloud-init 管理網路介面(network interface)。

    NewIP=$CurrentIP
    NewGW=$CurrentGW
    NewNM=$CurrentNM
    NewNS=$CurrentDNS
    
    # 確認沒有透過 cloud-init 管理網路介面(network interface)
    grep 'network: {config: disabled}' /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
    if [ "$?" = "0" ]; then
    cat <<EOF | sudo tee /etc/netplan/00-installer-config.yaml > /dev/null
    network:
      ethernets:
        $NetworkInterface:
          addresses: [$NewIP/$NewNM]
          gateway4: $NewGW
          nameservers:
            addresses: [$NewNS]
      version: 2
    EOF
    fi
    
    sudo netplan apply
    
  4. 如果要設定為全新的網路設定,可以參考以下設定:

    NetworkInterface=$(ifconfig | grep 'flags' | cut -d ':' -f 1 | grep -v 'lo')
    NewIP='192.168.1.201'
    NewGW='192.168.1.1'
    NewNM='24'
    NewNS='168.95.1.1,8.8.8.8'
    
    # 確認沒有透過 cloud-init 管理網路介面(network interface)
    grep 'network: {config: disabled}' /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
    if [ "$?" = "0" ]; then
    cat <<EOF | sudo tee /etc/netplan/00-installer-config.yaml > /dev/null
    network:
      ethernets:
        $NetworkInterface:
          addresses: [$NewIP/$NewNM]
          gateway4: $NewGW
          nameservers:
            addresses: [$NewNS]
      version: 2
    EOF
    fi
    

    如果 IP 發生變更,會導致目前的 SSH 遠端連線被中斷,所以建議在 Console 執行這個命令!

    sudo netplan apply
    

    如果 IP 沒有發生變更,你也可以利用利用 sudo netplan try 命令,先測試一下網路設定是否套用後還可以正常連線,如果在 --timeout 指定的秒數內沒有人按下 Enter,那就代表網路已經斷線了,此時 netplan 會自動復原網路設定,讓你可以繼續用原本的網路設定進行連線,以免遠端再也連不上該主機。

    sudo netplan try --timeout 3
    

從固定 IP 地址轉為 DHCP 伺服器取得動態 IP 地址

  1. 直接將網路介面設定轉換成從 DHCP 伺服器動態取得 IP 地址

    # 如果 VM 只有一張網路介面可以這樣取得網路介面名稱 (eth0)
    NetworkInterface=$(ifconfig | grep 'flags' | cut -d ':' -f 1 | grep -v 'lo')
    
    # 確認沒有透過 cloud-init 管理網路介面(network interface)
    grep 'network: {config: disabled}' /etc/cloud/cloud.cfg.d/subiquity-disable-cloudinit-networking.cfg
    if [ "$?" = "0" ]; then
    cat <<EOF | sudo tee /etc/netplan/00-installer-config.yaml > /dev/null
    # This is the network config written by 'subiquity'
    network:
      ethernets:
        $NetworkInterface:
          dhcp4: true
      version: 2
    EOF
    
  2. 套用 netplan 更新

    如果 IP 發生變更,會導致目前的連線被中斷,所以建議在 Console 執行這個命令:

    sudo netplan apply
    
  3. 取得新取得的 IP 地址

    ifconfig 'eth0' | grep 'inet '
    

相關連結