$1 我的Linux需求
Linux博大精深。我隻在此讨論一些我對線上Linux機器維護人員的基本需求,比如裝機,加硬碟,配網絡。隻讨論CentOS 6,或者類似的RHEL,當然Ubuntu也可以此類推,但是一些新特性不予讨論,因為我不懂,比如CentOS 7的xfs不予讨論,并不是說xfs不好,而是以目前我的Linux水準需要更新很多xfs的知識,駕馭需要時間。CentOS 7将ifconfig,netstat等原來常用的指令也幹掉了,用ip,lsof替換是更加好的工具,但是大部分的線上機器都應該還沒有更新到CentOS 7。下面我們以CentOS 6作為基礎,談我認為最基本的4點。
$1.1 最小化安裝
CentOS有一個minimal版本,相對于标準版去掉了很多Service,比如Network Manager,安裝最小版本以後的網絡配置是需要admin進行寫配置檔案的。我個人認為這樣是比較好的,因為這樣才能知道Linux核心真正關心的是哪些配置檔案,直達核心。一些必要的監控工具,完全可以通過yum install來完成。作為線上機器,還是最小化安裝,做到能不開的服務就不開,能關掉的端口就關掉,這樣既能将寶貴的硬體資源留下來給應用程式,也能夠做到更加的安全。
$1.2 足夠安全
除了将能關的端口關掉,能不用的服務關掉以外,安全還需要做到特定的服務隻能通路特定的内容。哪怕是root賬戶,不能通路的檔案和檔案夾還是不能通路,更加不能操作。開啟SELinux以後,能夠做到在不修改SELinux的情況下,指定的服務隻能通路指定的資源。對于ssh要做到關閉賬戶密碼登入,隻能通過秘鑰登入,這樣在保證秘鑰不被盜用的情況下是最安全的。
$1.3 資源按需排程
我們經常會遇到這樣一個問題,假設将磁盤sda挂載到/var目錄,但是由于log太多或者上傳的檔案等等其他因素将硬碟吃光了,再建立一塊sdb磁盤就無法挂載到/var目錄了,其實Linux自帶的lvm已經解決了這個問題,并且CentOS預設就是用lvm來管理磁盤的。我們需要學會如何格式化一塊硬碟為lvm,然後挂載到對應目錄,在空間被吃光前能夠添加一塊硬碟就自動擴容。
$1.4 網絡監控
Linux本地要利用好net_filter,也就是iptables,來規劃服務哪些網絡流量,抛棄哪些網絡流量。以及在進行組網的時候需要用router來進行網關的建立,在遇到網絡問題的時候通過netstat來檢視網絡通路異常。網絡這塊内容很多很雜,各種參數,TCP/IP協定棧等等,但是往往問題還就是出在網絡這塊,是以要給與高度的關注。
$2 Linux的理念與基礎
小談幾點我對Linux的認識。
$2.1 Linux的檔案系統
Linux将所有的事物都看成檔案,這一點人盡皆知。我想說的是,除了傳統的ext檔案系統,Linux在抽象不同的資源的時候其實有各種不同的檔案系統,都是從需求和使用出發,比如proc檔案系統就是針對程序的抽象,使得修改對應程序的值就可以直接改變程序的行為。再比如,對于遠端ssh登入的pts裝置,Linux有對應的devpts檔案系統。看下面表哥的type一欄。
file_system | dir | type | options | dump | pass |
---|---|---|---|---|---|
/dev/mapper/VolGroup-lv_root | / | ext4 | defaults | 1 | 1 |
UUID=xxx | /boot | ext4 | defaults | 1 | 2 |
/dev/mapper/VolGroup-lv_swap | swap | swap | defaults | ||
tmpfs | /dev/shm | tmpfs | defaults | ||
devpts | /dev/pt | devpts | gid=5,mod=620 | ||
sysfs | /sys | sysfs | defaults | ||
proc | /proc | proc | defaults |
$2.2 Linux的權限管理
Linux的
-rwxrwxrwx
權限管理也可謂人盡皆知,其實Linux自己也意識到了這樣的權限管理所帶來的一些局限性。首先rwx的權限管理是基于使用者群組的,并且隻是大緻的分為
owner|group|other
這三類,無法再作更加細粒度的劃分。有鑒于此,Linux目前預設是有ACL(Access Control List)管理的,所謂ACL就是能夠提供更加細粒度的使用者群組管理,比如可以明确哪個user可以有什麼樣的權限。如下示例
getfacl abc
# file: abc
# owner: someone
# group: someone
user::rw-
user:johny:r-x
group::r--
mask::r-x
other::r--
而SELinux提供了不基于使用者與組的權限管理,SELinux是基于應用程式的,什麼樣的應用程式可以使用什麼資源,對于這些資源這個應用程式能幹嘛,這個就是SELinux的管理方式。
$2.3 Linux上的Service
Linux上的Service組織得非常清晰,
/etc/init.d/
裡面包含了所有的Service啟動腳本,對應的二進制檔案在
/usr/bin 、 /usr/sbin 、 /usr/local/bin
等目錄下,一般而言配置檔案在
/etc/app_name
下,還有一個chkconfig的工具來管理各個
runlevel
下需要啟動的Service。這樣的約定俗成使得管理者在配置和使用的時候非常友善。Linux标準的Service都會将log記錄到
/var/log/messages
中,使得系統管理者不需要翻閱各種log,直接在
/var/log/messages
中就可以找到絕大部分的log來判斷目前系統是否正常。更甚者,
syslogd
被
rsyslogd
替換以後,可以将/var/log/messages中的内容通過UDP發送到遠端用專業的log分析工具進行分析。我們需要學習Linux上Service的這些優秀的程式設計習慣和技巧。
$3 磁盤
根據$1中的需求,下面是我記錄的一些基本的磁盤操作。
-
檢視磁盤的使用情況df -lah
-
檢視插入到磁盤驅動器中的硬碟; sd(a,b,c)(1,2,3),其中a是第一塊磁盤,b是第二塊磁盤,1,2,3表示磁盤上的主分區,最多4個。用fdisk從磁盤建立分區并且格式化。fdisk -l
- LVM(logical volume manager),主要就是滿足加硬碟就能直接寫資料的功能,而不會出現磁盤滿了,新的磁盤隻能挂載其他目錄的情況。lvm有幾個概念,VG, PV。将磁盤lvm格式化,建立PV, 建立VG,将建立的PV加入VG,然後在VG中建立lvm,然後就可以動态增加大小了。注意,将磁盤格式化為lvm,但是lv的格式化需要用ext,然後才能mount上去。參考這篇文章CentOS 6 卷組挂載硬碟教程
-
來挂載。如果要重新開機生效,必須将挂載資訊寫入到mount -t type(ext4|nfs) /dev/sdxn /path/dir
/etc/fstab
- 磁盤IO效率(IOPS)需要用
,vmstat
等工具來檢視。和性能相關的調優和監控留待後續文章詳述。top
$4 網絡
網絡的坑很多,需要把網絡搞通沒個3,4年很難。下面從網絡的配置檔案着手,簡單理一下網絡方面的内容。網絡最難的方面應該是如何搭建一個合理的高效的區域網路或者城域網,這個需要有專業的網絡知識。
$4.1 配置檔案
-
私有IP對應主機名/etc/hosts
-
nameserver DNS的IP/etc/resolv.conf
-
其中NETWORKING=要不要有網絡,HOSTNAME=主機名,NETWORKING_IPV6=支援ipv6否/etc/sysconfig/network
-
其中DEVICE=網卡代号,BOOTPROTO=是否使用dhcp,HWADDR,IPADDR,NETMASK,ONBOOT,GATEWAY/etc/sysconfig/network-scripts/ifcfg-xxx
$4.2 與網絡有關的一些指令
-
檢視路由的指令,特别是要看帶G的,表示gateway,而帶U的表示up。router -n
-
檢視所有啟動的netstat -anp
,tcp
,udp
的應用程式,以及他們的狀态,具體可以參考TCP/IP,JavaSocket簡單分析一文。unix stream
$5 安全
$5.1 PAM
PAM隻需要簡單了解就行,是一個可插拔的認證子產品。我的了解是:開發Linux的極客們搞出來的可複用的一個元件。舉個例子,現在有一個app,想要驗證目前的登入使用者是否有權限操作某個目錄,那麼在PAM裡面有現成的子產品,app隻需要
include
這個子產品,給出一個配置檔案,就可以了。有一個非常好的關于PAM的視訊教程,請看這裡
- PAM是應用程式用來進行身份驗證的。早期的身份驗證和應用程式本身耦合,後來把身份驗證單獨抽出來,通過PAM來進行管理
-
是能用pam來進行管理的應用程式PAM設定,在安裝應用程式的時候安裝。/etc/pam.d/xxx
,/etc/security/mmm
是一套。/lib/security/pam_mmm
$5.2 SELinux
SELinux也有一個非常好的視訊教程,請看這裡
-
來檢視SELinux是否被啟用getenforce
-
啟用SELinux/etc/sysconfig/selinux enforcing
- SELinux對“運作程式”配置和檢查其是否有權限操作“對象”(檔案系統),而普通的ACL(rwx)就是根據檔案所屬owner及其組來判斷。SELinux是看可執行檔案的type和目錄檔案的type是否相容,來決定可執行檔案是否能操作資源
$5.3 防火牆
下面是學習時候的一些摘錄。特别一點,要開啟核心參數
net.ipv4.ip_forward=1
,在
/etc/sysctl.conf
檔案中,用
sysctl -p
來儲存。所謂ip_forward指的是核心提供的從一個iface到另外一個iface的IP包轉發,比如将IP包從192.168.1.10的eth0轉發到10.0.0.123的eth1上。防火牆配置是需要專業技能的。
- tcp_wrapper需要libwrap.so的支援,可執行檔案在
出來沒有ldd bin_file
的,都不能用tcp_wrapperlibwrap.so
- iptables是按照規則進行短路判斷的,即 滿足條件1->執行action1->結束
- iptables-save來更加清晰的檢視
- 先删掉全部規則,然後添加,比較簡單。添加的時候,先添加政策,再添加細部規則。一般來講,我們需要關注的是filter這個表的INPUT與OUTPUT
- iptables -A(I) INPUT(OUTPUT,FORWARD) -i(o) iface -p tcp(ump,imp,all) -s (!)source -d dest -j ACCEPT(REJECT,DROP), 還支援的參數 —dport —sport
$6 工具
一個好的Linux指令參考網站
$6.1 CPU
-
特别注意loadtop
-
和ps aux
特别注意程序狀态ps -ef
-
表示每秒采集一次vmstat 1
-
檢視所有cpu相關的運作時間sar -u 1
$6.2 Memory
-
free
-
注意其中的swap ram block之間的關系vmstat 1
-
記憶體使用率sar -r 1
-
檢視swap,查詢是否由于記憶體不足産生大量記憶體交換sar -W 1
$6.3 IO
-
查詢哪個程序占用了這個端口号lsof -i:port
-
使用者打開的檔案lsof -u username
-
程序打開的檔案lsof -p pid
雜項
關于安裝好系統之後的運作腳本,這邊有一個參考
#!/bin/bash
#################################################
# author huachao
# date 2015-12-09
# email [email protected]
# web blog.huachao.me
#################################################
flagFile="/root/centos6-init.executed"
precheck(){
if [[ "$(whoami)" != "root" ]]; then
echo "please run this script as root ." >&2
exit 1
fi
if [ -f "$flagFile" ]; then
echo "this script had been executed, please do not execute again!!" >&2
exit 1
fi
echo -e "\033[31m WARNING! THIS SCRIPT WILL \033[0m\n"
echo -e "\033[31m *1 update the system; \033[0m\n"
echo -e "\033[31m *2 setup security permissions; \033[0m\n"
echo -e "\033[31m *3 stop irrelevant services; \033[0m\n"
echo -e "\033[31m *4 reconfig kernel parameters; \033[0m\n"
echo -e "\033[31m *5 setup timezone and sync time periodically; \033[0m\n"
echo -e "\033[31m *6 setup tcp_wrapper and netfilter firewall; \033[0m\n"
echo -e "\033[31m *7 setup vsftpd; \033[0m\n"
sleep 5
}
yum_update(){
yum -y update
#update system at 5:40pm daily
echo "40 3 * * * root yum -y update && yum clean packages" >> /etc/crontab
}
permission_config(){
#chattr +i /etc/shadow
#chattr +i /etc/passwd
}
selinux(){
sed -i 's/SELINUX=disabled/SELINUX=enforcing/g' /etc/sysconfig/selinux
setenforce 1
}
stop_services(){
for server in `chkconfig --list |grep 3:on|awk '{print $1}'`
do
chkconfig --level 3 $server off
done
for server in crond network rsyslog sshd iptables
do
chkconfig --level 3 $server on
done
}
limits_config(){
cat >> /etc/security/limits.conf <<EOF
* soft nproc 65535
* hard nproc 65535
* soft nofile 65535
* hard nofile 65535
EOF
echo "ulimit -SH 65535" >> /etc/rc.local
}
sysctl_config(){
sed -i 's/net.ipv4.tcp_syncookies.*$/net.ipv4.tcp_syncookies = 1/g' /etc/sysctl.conf
sed -i 's/net.ipv4.ip_forward.*$/net.ipv4.ip_forward = 1/g' /etc/sysctl.conf
cat >> /etc/sysctl.conf <<EOF
net.ipv4.tcp_max_syn_backlog = 65536
net.core.netdev_max_backlog = 32768
net.core.somaxconn = 32768
net.core.wmem_default = 8388608
net.core.rmem_default = 8388608
net.core.rmem_max = 16777216
net.core.wmem_max = 16777216
net.ipv4.tcp_timestamps = 0
net.ipv4.tcp_synack_retries = 2
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_mem = 94500000 915000000 927000000
net.ipv4.tcp_max_orphans = 3276800
net.ipv4.ip_local_port_range = 1024 65535
EOF
sysctl -p
}
sshd_config(){
if [ ! -f "/root/.ssh/id_rsa.pub" ]; then
ssh-keygen -t rsa -P '' -f /root/.ssh/id_rsa
cat /root/.ssh/id_rsa.pub >> /root/.ssh/authorized_keys
chmod 600 /root/.ssh/authorized_keys
fi
#sed -i '/^#Port/s/#Port 22/Port 65535/g' /etc/ssh/sshd_config
sed -i '/^#UseDNS/s/#UseDNS no/UseDNS yes/g' /etc/ssh/sshd_config
#sed -i 's/#PermitRootLogin yes/PermitRootLogin no/g' /etc/ssh/sshd_config
sed -i 's/#PermitEmptyPasswords yes/PermitEmptyPasswords no/g' /etc/ssh/sshd_config
sed -i 's/PasswordAuthentication yes/PasswordAuthentication no/g' /etc/ssh/sshd_config
/etc/init.d/sshd restart
}
time_config(){
#timezone
echo "TZ='Asia/Shanghai'; export TZ" >> /etc/profile
# Update time
if [! -f "/usr/sbin/ntpdate"]; then
yum -y install ntpdate
fi
/usr/sbin/ntpdate pool.ntp.org
echo "30 3 * * * root (/usr/sbin/ntpdate pool.ntp.org && /sbin/hwclock -w) &> /dev/null" >> /etc/crontab
/sbin/service crond restart
}
iptables(){
cat > /etc/sysconfig/iptables << EOF
# Firewall configuration written by system-config-securitylevel
# Manual customization of this file is not recommended.
*filter
:INPUT DROP [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:syn-flood - [0:0]
-A INPUT -i lo -j ACCEPT
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 80 -j ACCEPT
-A INPUT -p icmp -m limit --limit 100/sec --limit-burst 100 -j ACCEPT
-A INPUT -p icmp -m limit --limit 1/s --limit-burst 10 -j ACCEPT
-A INPUT -p tcp -m tcp --tcp-flags FIN,SYN,RST,ACK SYN -j syn-flood
-A INPUT -j REJECT --reject-with icmp-host-prohibited
-A syn-flood -p tcp -m limit --limit 3/sec --limit-burst 6 -j RETURN
-A syn-flood -j REJECT --reject-with icmp-port-unreachable
COMMIT
EOF
/sbin/service iptables restart
source /etc/profile
}
other(){
# initdefault
sed -i 's/^id:.*$/id:3:initdefault:/' /etc/inittab
/sbin/init q
# PS1
#echo 'PS1="\[\e[32m\][\[\e[35m\]\u\[\e[m\]@\[\e[36m\]\h \[\e[31m\]\w\[\e[32m\]]\[\e[36m\]$\[\e[m\]"' >> /etc/profile
# Wrong password five times locked 180s
sed -i '4a auth required pam_tally2.so deny=5 unlock_time=180' /etc/pam.d/system-auth
}
vsftpd_setup(){
yum -y install vsftpd
mv /etc/vsftpd/vsftpd.conf /etc/vsftpd/vsftpd.conf.bak
touch /etc/vsftpd/chroot_list
setsebool -P ftp_home_dir=1
cat >> /etc/vsftpd/vsftpd.conf <<EOF
# normal user settings
local_enable=YES
write_enable=YES
local_umask=022
chroot_local_user=YES
chroot_list_enable=YES
chroot_list_file=/etc/vsftpd/chroot_list
local_max_rate=10000000
# anonymous settings
anonymous_enable=YES
no_anon_password=YES
anon_max_rate=1000000
data_connection_timeout=60
idle_session_timeout=600
# ssl settings
#ssl_enable=YES
#allow_anon_ssl=NO
#force_local_data_ssl=YES
#force_local_logins_ssl=YES
#ssl_tlsv1=YES
#ssl_sslv2=NO
#ssl_sslv3=NO
#rsa_cert_file=/etc/vsftpd/vsftpd.pem
# server settings
max_clients=50
max_per_ip=5
use_localtime=YES
dirmessage_enable=YES
xferlog_enable=YES
connect_from_port_20=YES
xferlog_std_format=YES
listen=YES
pam_service_name=vsftpd
tcp_wrappers=YES
#banner_file=/etc/vsftpd/welcome.txt
dual_log_enable=YES
pasv_min_port=65400
pasv_max_port=65410
EOF
chkconfig --level 3 vsftpd on
service vsftpd restart
}
main(){
precheck
printf "\033[32m================%40s================\033[0m\n" "updating the system "
yum_update
printf "\033[32m================%40s================\033[0m\n" "re-config permission "
permission_config
printf "\033[32m================%40s================\033[0m\n" "enabling selinux "
selinux
printf "\033[32m================%40s================\033[0m\n" "stopping irrelevant services "
stop_services
printf "\033[32m================%40s================\033[0m\n" "/etc/security/limits.config "
limits_config
printf "\033[32m================%40s================\033[0m\n" "/etc/sysctl.conf "
sysctl_config
printf "\033[32m================%40s================\033[0m\n" "sshd re-configuring "
sshd_config
printf "\033[32m================%40s================\033[0m\n" "configuring time "
time_config
printf "\033[32m================%40s================\033[0m\n" "configuring firewall "
# iptables
printf "\033[32m================%40s================\033[0m\n" "someother stuff "
other
printf "\033[32m================%40s================\033[0m\n" "done! rebooting "
touch "$flagFile"
sleep 5
reboot
}
main