天天看點

使用shell/python擷取hostname/fqdn釋疑

一直以來被Linux的hostname和fqdn(Fully Qualified Domain Name)困惑了好久,今天專門抽時間把它們的使用細節弄清了。

一、設定hostname/fqdn

在Linux系統内設定hostname很簡單,如:

$ hostname florian
           

如果要設定fqdn的話,需要對/etc/hosts進行配置。

$ cat /etc/hosts
127.0.0.1 localhost
192.168.1.1 florian.test.com florian
           

/etc/hosts配置檔案的格式是:

ip fqdn [alias]...
           

即第一列為主機ip位址,第二列為主機fqdn位址,第三列以後為别名,可以省略,否則至少要包含hostname。

上述配置檔案的配置項的第一行為localhost的配置,第二行為主機名florian配置fqdn=florian.test.com,ip=192.168.1.1。

至于fqdn的域名字尾,最好和檔案/etc/sysconfig/network的HOSTNAME配置保持一緻:

$ cat /etc/sysconfig/network
NETWORKING=yes
HOSTNAME=test.com
           

二、檢視hostname/fqdn

配置完成後,可以使用shell指令檢視hostname和fqdn:

$ hostname && hostname -f 
florian
florian.test.com
           

使用ping去測試hostname的ip映射是否成功。

$ ping florian
PING florian.test.com (192.168.1.1) 56(84) bytes of data.

$ ping florian.test.com
PING florian.test.com (192.168.1.1) 56(84) bytes of data.
           

也可以使用python指令擷取hostname和fqdn。

$ python 
Python 2.6.6 (r266:84292, Dec  7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> socket.gethostname()
'florian'
>>> socket.getfqdn()    
'florian.test.com'
           

三、使用ip設定hostname帶來的fqdn問題

以上描述了正常設定hostname和fqdn的方法,但是有時會使用ip位址直接作為hostname,此時會有些不同。

$ hostname 192.168.1.1
$ hostname && hostname -f
192.168.1.1
192.168.1.1
           

我們發現使用ip作為hostname後,使用shell指令查詢hostname和fqdn都是ip位址!!!這是因為DNS協定會解析hostname的内容,當發現其為ip位址時,則不會再去查詢/etc/hosts檔案。

再使用python檢視一下,會發現python擷取的fqdn竟然還是florian.test.com!!!

$ python
Python 2.6.6 (r266:84292, Dec  7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket 
>>> socket.gethostname()
'192.168.1.1'
>>> socket.getfqdn()
'florian.test.com'
           

即便是重新整理dns緩存也無濟于事:

$ service nscd reload
           

将/etc/hosts檔案的第二行注釋:

cat /etc/hosts
127.0.0.1 localhost
# 192.168.1.1 florian.test.com florian
           

重新整理dns緩存:

$ service nscd reload

我們發現fqdn恢複正常了。

$ python
Python 2.6.6 (r266:84292, Dec  7 2011, 20:48:22) 
[GCC 4.4.6 20110731 (Red Hat 4.4.6-3)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket 
>>> socket.gethostname()
'192.168.1.1'
>>> socket.getfqdn()
'192.168.1.1'
           

之是以會有這樣的行為,是因為python解析fqdn的邏輯和DNS并不完全一緻,它會根據hostname查詢對應的ip位址,然後在/etc/hosts内擷取ip位址對應的配置行(第一行有效),然後解析fqdn列和alias列,并傳回第一個包含字元'.'的對應列的值。

是以,使用ip設定hostname時,需要注意兩點:

  • 首先,将hostname設定為ip位址
  • 其次,将/etc/hosts内包含該ip的配置項移除

為了保險起見,我們可以在/etc/hosts内盡可能靠前的位置添加如下配置:

cat /etc/hosts
127.0.0.1 localhost
192.168.1.1 192.168.1.1
           

這樣,即便是之後有包含該ip的配置項也不會生效,python會優先解析第二行的配置項,并擷取和ip位址完全一樣的fqdn位址。當然,使用shell指令hostname擷取fqdn也不會出錯,因為hostname已經被設為ip位址形式了。

四、參考資料

  • Linux下配置FQDN: https://onebitbug.me/2014/06/25/settings-fqdn-in-linux/
  • linux基礎:設定FQDN和Hostname: http://www.chenshake.com/linux-foundation-set-fqdn-hostname/
  • Is it valid for a hostname to start with a digit?: http://serverfault.com/questions/638260/is-it-valid-for-a-hostname-to-start-with-a-digit

作者:Florian

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連結,否則作者保留追究法律責任的權利。

若本文對你有所幫助,您的

關注

推薦

是我分享知識的動力!