记一次 RedHat 网络配置,回顾 KISS 原则
最近搭建实验室网络和服务器,初试 RedHat EL 发行版。 感受企业级发行版和 Geek 级发行版的差异,重新体会 ArchLinux 的 KISS 原则。
先介绍下实验室的网络环境,一共两间房:楼下的机房和楼上的实验室。 机房有一台 H3C ER 路由器和一台交换机,实验室有一个路由器、一个交换机,加两个 WiFi 热点。 机房有两根线接上来到实验室。 我的任务是把机房的两台 RedHat 接入实验室网络并提供代理和 VPN 服务。 麻烦在于我只知道这两台机器是 RedHat,其他一无所知。
用 Console-COM 接口重置路由和重新接通实验室和机房网络之后,终于可以 ping 到我要去配置的服务器了。 本文的故事从登录到服务器开始。
重置密码成功
当然,首先要重置 root 密码。重启、进入 grub、编辑启动项、选择并编辑内核参数、最后加一个 1
、启动并进入单用户模式。然后的操作就熟为人知了:重置 root 密码,添加用户并加入 sudoers
:
passwd
useradd harttle -g wheel
passwd harttle
vim /etc/sudoers # 允许wheel group
exit
根据
archlinux
来的习惯,我甚至准备yum install vim sudoers
。惊喜地发现这些软件RHEL
都内置了,也许编辑sudoers
也并非必要。像centOS
一样,一经安装便是一个完整的服务器操作系统,而且提供长期维护的版本,确实是服务器的绝佳选择。
此时我已经是管理员用户了,那么在系统启动后登录我的账号,一眼就认出来四年前见过的 Gnome,怀旧的情愫油然而生。接下来配置网络!
配置 DHCP 失败
懒得找从哪里打开 console,于是 Ctrl+Alt+F1
打开 TTY1,居然是不响应键盘的启动 log!然后继续 Ctrl+Alt+F2
打开 TTY2,OK,登录。然后习惯性地开始配置网络:
ip link
ip link set eth0 up
ip addr add 192.168.x.x dev eth0
ip link set eth0 netmast 255.255.255.0 broadcast 192.168.1.255
这样设置好 IP 与掩码之后才会与路由器位于同一网段,才能登录到路由器。ArchLinux 中甚至没有内置
ifconfig
(在net_tools
中)和iwconfig
(在wireless_tools
中),因为ip
就可以完成所有配置呀!ArchLinux 就是这么名副其实的 Simple。
接着用 firefox 去路由器,绑定静态 DHCP。然后呢,就来通过 DHCP 来获得地址吧:
$ dhcpcd eth0
Command dhcpcd not found
$ ps aux | grep dhcp # 没有~~~~(>_<)~~~~
$ dhc <Tab> <Tab>
$ dhclient eth0 # 原来是这样
$ ip addr # 仍然没分配到地址
如果这时候你希望从 Gnome 桌面的网络连接模块里得到信息的话,我告诉你里面甚至连本地连接接口都没有!不要使用 GUI 做系统管理。
来,开始排错!Ctrl+Alt+F3
打开 TTY3,监听 DHCP 报文:
tcpdump -n -i eth0 port 67 or port 68
回到 TTY2,再来一次 dhclient eth0
,提示已经在运行。哦,原来是后台进程,ps
出来 kill
掉。再来一次 dhclient eth0
,提示已发送信号给 DHCP 客户端守护进程,同时 TTY3 没有任何响动。擦,是后台进程但不是守护进程!总之 dhclient
并未发送 DHCP 报文,也没有提示错误或者警告 。
在 ArchLinux 中
dhcpcd
是 DHCP 客户端守护进程,每次命令的调用都会发送一次 DHCP 报文,立竿见影。
配置 SSH 失败
没办法,就用现在的静态 IP 继续设置 sshd
,这样我就可以远程操作了!
vim /etc/ssh/sshd_config
# 禁止root用户登录、检查端口是否正确、设置AliveInteval、AllowUsers、etc。
在路由器映射 22 号端口后测试 ssh!在本地 ssh harttle@localhost
登录成功!ssh harttle@<路由器公网IP>
连接失败!同时 tcpdump port 22
可以看到收到了路由器转发来的 SSH 报文,难道是路由表?
vim /etc/sysconfig/iptables
# 检查filter是否REJECT了eth0上与ssh有关的包
路由表没问题,试着重启 service iptables restart
,仍不起作用。到此为止,回家睡觉!
按照 RedHat 的习惯重新配置
第二天,对上述的失败反思了很久。用了这么久的 ArchLinux,相信如上的命令没有问题。来一本鸟哥,学习一下 CentOs,毕竟和 RedHat 是一样的源码。读后恍然大悟:
vim /etc/sysconfig/network-scripts/ifcfg-eth0
# 发现这里是原来管理员的设置,静态IP与静态路由,但开启了dhcp,改正之。
/etc/init.d/network restart
# 一切都好了。DHCP正常、SSH连接成功。
原来 RedHat 是这样配置的。确实 Simple,满足服务器操作系统的一大需求。 为什么这样 Simple 却花费了我如此多的功夫呢?我的命令也正确为什么没有得到应有的结果?这正是因为 RedHat 并无 KISS 原则 :
Keep it simple, stupid.
首先根据 RFC-2131,DHCP 作为局域网内的协议,其功能是:为主机提供 Internet 配置。在多数实现中该配置都包括了 IP、掩码、广播、DNS、路由。然而 dhclient
未能将得到的这些字段都进行设置,因为 /etc/sysconfig/network-scripts/ifcfg-eth0
是这样配置的:
BOOTPROTO=dhcp
IPADDR=192.168.1.72
NETMASK=255.255.255.0
GATEWAY=192.168.1.2
这里的路由是 192.168.1.2
,导致 sshd
可以接收到 SSH 报文,但却发送不出去。于是局域网内可以 SSH(根据 RFC791 的 IP 协议,此时不经过路由,而是通过 ARP 来直接寻找 MAC 地址),但不能通过局域网的路由从外部访问。
严格地说该配置是有误的。开启 DHCP,却指定了静态网络配置。RedHat 没有抱怨而是选择了容错,这样的策略使得网络配置更加灵活,例如可以部分设置采用 DHCP ;但造成了 dhclient
命令没有达到预期的结果。其原因很简单, 该策略比较 complex,不满足 simple 原则 。
其次,dhclient
只是发送信号给守护进程,而不保证执行用户的意图:发送 DHCP 报文。这样的设计虽然通过更复杂的逻辑避免了额外的 payload,其后果就是未能执行承诺的操作。原因仍然很显然, 这样的策略比较 smart,不满足 stupid 原则 。让你发 DHCP 你就发 DHCP,自作聪明地忽略该操作将会让 tcpdump
无法追溯到出了什么问题!
RedHat 服务器配置
既然装好了,把常用的配置都记录一下,以免今后忘记。我这里的版本是 RedHat6.3。
yum 源
所谓“源”不就是软件包的获取地址,相同平台上系统,具有相同的系统调用,自然软件包是通用的。 CentOS 是基于 RedHat 的源文件开发的,因此如果你不想支付数千元服务费给红帽,就使用 CentOS 的源。 教育网源对教育网用户是最方便的,这个 ustc 的源就很好。拷过来!
因为 RedHat 和 CentOS 的 $releasever
产生方式不一样,会导致源的 url 有区别,结果就是获取源时发生 HTTP 404。
进入 /etc/yum.conf
和 /etc/yum.repos.d/rhel-source.repo
,用 vim 替换一下~(:%s/\$releasever/6/g
)
然后更新:
yum clean all
yum makecache
yum -y update
VPN 或代理
为了更好地利用 Internet,外网服务器最常搭建的就是 VPN 服务。 VPN 协议有多种,而 pptp、l2tp 需要路由器支持。 当然可以使用 openVPN 等上层协议的 VPN 工具,其代价便是客户端都需要安装特定的程序。 于是我们决定使用代理服务器,以当前较流行的 squid 为例。
而普通路由器之所以能让多台主机共享互联网 IP,依赖于其 NAT 地址转换。NAT 地址转换需要用到 TCP/UDP 的端口字段。pptp 是直接运行在 IP 层之上的协议,并无端口字段,一些路由器可以利用它的其他无用字段来实现 NAT 穿透,于是 pptp 协议需要特殊的路由器。
更改路由表的 filter 表,即 RedHat 防火墙:
# file: /etc/sysconfig/iptables
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3128 -j ACCEPT
安装 squid 后,配置 squid:
# file: /etc/squid/squid.conf
http_access allow all
启动 squid:
# 开机启动
chkconfig squid on
# 启动
service squid start
再通过路由器的端口映射就可以使用了。
本文采用 知识共享署名 4.0 国际许可协议(CC-BY 4.0)进行许可,转载注明来源即可: https://harttle.land/2014/10/09/kiss.html。如有疏漏、谬误、侵权请通过评论或 邮件 指出。