# uname -a # 獲取內核版本(和BSD版本)
# lsb_release -a
# 顯示任何 LSB 發行版版本信息
# cat /etc/SuSE-release # 獲取 SuSE 版本
# cat /etc/debian_version
# 獲取 Debian 版本
使用 /etc/DISTR
-release 其中DISTR(發行代號)=
lsb
(Ubuntu), redhat, gentoo, mandrake, sun (Solaris), 等等。
# uptime # 顯示系統開機運行到現在經過的時間
# hostname
# 顯示系統主機名
# hostname -i # 顯示主機的 IP 地址
# man hier
# 描述文件系統目錄結構# last reboot # 顯示系統最後重啓的歷史記錄
硬件信息
內核檢測到的硬件信息
# dmesg # 檢測到的硬件和啓動的消息
# lsdev
# 關於已安裝硬件的信息譯註:許多 Linux 發行版需要自行安裝,如:apt-get install procinfo# dd if=/dev/mem bs=1k skip=768 count=256 2>/dev/null | strings -n 8 # 讀取 BIOS 信息
Linux
# cat /proc/cpuinfo # CPU 訊息
# cat /proc/meminfo
# 內存信息
# grep MemTotal /proc/meminfo # 顯示物理內存大小
# watch -n1 'cat /proc/interrupts'
# 監控內核處理的所有中斷
# free -m # 顯示已用和空閒的內存信息 (-m 爲 MB)譯註:包括 SWAP 分區
# cat /proc/devices
# 顯示當前核心配置的設備
# lspci -tv # 顯示 PCI 設備
# lsusb -tv
# 顯示 USB 設備
# lshal # 顯示所有設備屬性列表
# dmidecode
# 顯示從 BIOS 中獲取的硬件信息
FreeBSD
# sysctl hw.model # CPU 訊息
# sysctl hw
# 得到很多硬件信息
# sysctl vm # 虛擬內存使用情況
# dmesg | grep "real mem"
# 物理內存
# sysctl -a | grep mem # 內核內存的設置和信息
# sysctl dev
# 顯示當前核心配置的設備
# pciconf -l -cv # 顯示 PCI 設備
# usbdevs -v
# 顯示 USB 設備# atacontrol list # 顯示 ATA 設備
顯示狀態信息
以下的命令有助於找出正在系統中運行着的程序。
# top # 顯示和更新使用 cpu 最多的進程
# mpstat 1
# 顯示進程相關的信息
# vmstat 2 # 顯示虛擬內存的狀態信息
# iostat 2
# 顯示 I/O 狀態信息(2 秒 間隙)
# systat -vmstat 1 # 顯示 BSD 系統狀態信息(1 秒 間隙)
# systat -tcp 1
# 顯示 BSD TCP 連接信息(也可以試試 -ip)
# systat -netstat 1 # 顯示 BSD 當前網絡連接信息
# systat -ifstat 1
# 顯示 BSD 當前網卡帶寬信息
# systat -iostat 1 # 顯示 BSD CPU 和磁盤使用情況
# tail -n 500 /var/log/messages
# 顯示最新500條內核/系統日誌的信息# tail /var/log/warn # 顯示系統警告信息(看syslog.conf)
用戶
# id # 顯示當前用戶和用戶組的 ID
# last
# 列出目前與過去登入系統的用戶相關信息譯註:單獨執行 last 指令,它會讀取位於 /var/log 目錄下,名稱爲 wtmp 的文件,並把該給文件的內容記錄的登入系統的用戶名單全部顯示出來。
# who # 顯示目前登入系統的用戶信息
# groupadd admin
# 建立新組"admin"和添加新用戶 colin 並加入 admin 用戶組(Linux/Solaris)
# useradd -c "Colin Barschel" -g admin -m colin
# userdel colin # 刪除用戶 colin(Linux/Solaris)
# adduser joe
# FreeBSD 添加用戶 joe(交互式)
# rmuser joe # FreeBSD 刪除用戶 joe(交互式)
# pw groupadd admin
# 在 FreeBSD 上使用 pw
# pw groupmod admin -m newmember # 添加新用戶到一個組
# pw useradd colin -c "Colin Barschel" -g admin -m -s /bin/tcsh
# pw userdel colin; pw groupdel admin
加密過的密碼存儲在 /etc/shadow (Linux and Solaris) 或 /etc/master.passwd (FreeBSD) 中. 如果手動修改了 master.passwd,需要運行 # pwd_mkdb -p master.passwd
來重建數據庫。
使用 nologin 來臨時阻止所有用戶登錄(root除外)。用戶登錄時將會顯示 nologin 中的信息。
# echo "Sorry no login now" > /etc/nologin # (Linux)
# echo "Sorry no login now" > /var/run/nologin
# (FreeBSD)
限制
某些應用程序需要設置可打開最大文件和 socket 數量(像代理服務器,數據庫)。 默認限制通常很低。
Linux
每 shell/腳本
shell 的限制是受 ulimit
支配的。使用 ulimit
-a
可查看其狀態信息。 舉個例子,改變可打開最大文件數從 1024 到 10240,可以這麼做:
# ulimit -n 10240 # 這隻在shell中有用
ulimit
命令可以使用在腳本中來更改對此腳本的限制。
每 用戶/進程
登錄用戶和應用程序的限制可以在 /etc/security/limits.conf
中配置。舉個例子:
# cat /etc/security/limits.conf
* hard nproc 250 # 限制所有用戶進程數
asterisk hard nofile 409600
# 限制應用程序可打開最大文件數
系統級
用sysctl來設置內核限制。要使其永久,可以在 /etc/sysctl.conf
中進行配置。
# sysctl -a # 顯示所有系統限制
# sysctl fs.file-max
# 顯示系統最大文件打開數
# sysctl fs.file-max=102400 # 更改系統最大文件打開數
# cat /etc/sysctl.conf
fs.file-max=102400
# 在 sysctl.conf 中的永久項# cat /proc/sys/fs/file-nr # 在使用的文件句柄數
FreeBSD
每 shell/腳本
在 csh 或 tcsh 中使用 limits
命令,在 sh 或 bash 中使用 ulimit
命令。
每 用戶/進程
在 /etc/login.conf
中配置登錄後的默認限制。未作限制的值爲系統最大限制值。
系統級
內核限制同樣使用 sysctl 來設置。永久配置,在 /etc/sysctl.conf
或 /boot/loader.conf
中。其語法與
Linux 相同,只是鍵值不同。
# sysctl -a # 顯示所有系統限制
# sysctl kern.maxfiles=XXXX
# 最大文件描述符數
kern.ipc.nmbclusters=32768 # 在 /etc/sysctl.conf 中的永久項
kern.maxfiles=65536
# Squid譯註:代理服務器 通常用這個值
kern.maxfilesperproc=32768
kern.ipc.somaxconn=8192 # TCP 列隊。apache/sendmail 最好用這個值
# sysctl kern.openfiles
# 在使用的文件描述符數# sysctl kern.ipc.numopensockets # 已經開啓的 socket 數目
詳情請看 FreeBSD 手冊 11章http://www.freebsd.org/handbook/configtuning-kernel-limits.html。
Solaris
在 /etc/system
中的下列設置,會提高每個進程可以打開最大文件描述符的數量:
set rlim_fd_max = 4096 # 一個進程可以打開文件描述符的"硬"限制
set rlim_fd_cur = 1024
# 一個進程可以打開文件描述符的"軟"限制
運行級別
Linux
一旦內核加載完成,內核會啓動 init
進程,然後運行 rc
譯註:/etc/rc.d/rc
腳本,之後運行所有屬於其運行級別的命令腳本。這些腳本都儲存在 /etc/rc.d/rcN.d 中(N代表運行級別),並且都建立着到 /etc/init.d 子目錄中命令腳本程序的符號鏈接。
默認運行級別配置在 /etc/inittab 中。它通常爲 3 或 5:
# grep default: /etc/inittab
id:3:initdefault:
可以使用 init
來改變當前運行級別。舉個例子:
# init 5 # 進入運行級別 5
運行級別列表如下:
- 0 系統停止
- 1 進入單用戶模式(也可以是 S)
- 2 沒有 NFS 特性的多用戶模式
- 3 完全多用戶模式(正常操作模式)
- 4 未使用
- 5 類似於級別3,但提供 XWindow 系統登錄環境
- 6 重新啓動系統
使用 chkconfig
工具控制程序在一個運行級別啓動和停止。
# chkconfig --list # 列出所有 init 腳本
# chkconfig --list sshd
# 查看 sshd 在各個運行級別中的啓動配置
# chkconfig sshd --level 35 on # 對 sshd 在級別 3 和 5 下創建啓動項
# chkconfig sshd off
# 在所有的運行級別下禁用 sshd
Debian 和基於Debian 發行版像 Ubuntu 或 Knoppix 使用命令 update-rc.d
來管理運行級別腳本。默認啓動爲 2,3,4 和 5,停止爲 0,1 和 6。
# update-rc.d sshd defaults # 設置 sshd 爲默認啓動級別
# update-rc.d sshd start 20 2 3 4 5 . stop 20 0 1 6 .
# 用顯示參數
# update-rc.d -f sshd remove # 在所有的運行級別下禁用 sshd
# shutdown -h now (或者 # poweroff)
# 關閉停止系統
FreeBSD
BSD 啓動步驟不同於 SysV, 她沒有運行級別。她的啓動狀態(單用戶,有或沒有 XWindow)被配置在 /etc/ttys
中。所有的系統腳本都位於 /etc/rc.d/
中,第三方應用程序位於 /usr/local/etc/rc.d/
中。service
的啓動順序被配置在 /etc/rc.conf
和/etc/rc.conf.local
中。默認行爲可在 /etc/defaults/rc.conf
中進行配置。
這些腳本至少響應 start|stop|status.
# /etc/rc.d/sshd status
sshd is running as pid 552.
# shutdown now # 進入單用戶模式
# exit
# 返回到多用戶模式
# shutdown -p now # 關閉停止系統
# shutdown -r now
# 重新啓動系統
同樣可以使用進程 init
進入下列狀態級別。舉個例子: #
init 6
爲重啓。
- 0 停止系統並關閉電源 (信號
USR2
) - 1 進入單用戶模式 (信號
TERM
) - 6 重新啓動 (信號
INT
) - c 阻止進一步登錄 (信號
TSTP
) - q 重新檢查 ttys(5) 文件 (信號
HUP
)
重設 root 密碼
Linux 方法 1
在引導加載器(lilo 或 grub)中,鍵入如下啓選項:
init=/bin/sh
內核會掛載 root 分區,進程 init
會啓動 bourne shell 而不是 rc
,然後是運行級別。使用命令 passwd
設置密碼然後重啓。別忘了需要在單用戶模式下做這些動作。
如果重啓後 root 分區被掛載爲只讀,重新掛在它爲讀寫:
# mount -o remount,rw /
# passwd # 或者刪除 root 密碼 (/etc/shadow)
# sync; mount -o remount,ro /
# sync 在重新掛在爲只讀之前 sync 一下# reboot
FreeBSD 和 Linux 方法 2
FreeBSD 不會讓你這麼做。解決方案是用其他操作系統(像系統緊急修復光盤)掛載 root 分區,然後更改密碼。
- 用 live cd 或安裝盤啓動進入修復模式後,會得到一個 shell。
- 用 fdisk 查找 root 分區。比如:fdisk /dev/sda
- 掛載它並使用 chroot 命令:
# mount -o rw /dev/ad4s3a /mnt
# chroot /mnt # 改變程序執行時所參考的根目錄位置爲 /mnt
# passwd
# reboot
內核模塊
Linux
# lsmod # 列出所有已載入內核的模塊
# modprobe isdn
# 載入 isdn 模塊
FreeBSD
# kldstat # 列出所有已載入內核的模塊
# kldload crypto
# 載入 crypto 模塊
編譯內核
Linux
# cd /usr/src/linux
# make mrproper # 清除所有東西,包括配置文件
# make oldconfig
# 從當前內核配置文件的基礎上創建一個新的配置文件
# make menuconfig # 或者 xconfig (Qt) 或者 gconfig (GTK)
# make
# 創建一個已壓縮的內核映像文件
# make modules # 編譯模塊
# make modules_install
# 安裝模塊
# make install # 安裝內核
# reboot
FreeBSD
要改變和重建內核,需要拷貝源配置文件然後編輯它。當然也可以直接編輯 GENERIC
文件。
# cd /usr/src/sys/i386/conf/
# cp GENERIC MYKERNEL
# cd /usr/src
# make buildkernel KERNCONF=MYKERNEL
# make installkernel KERNCONF=MYKERNEL
要重建完全的操作系統:
# make buildworld # 構建完全的系統,但不是內核
# make buildkernel
# 使用 KERNCONF 配置文件編譯內核
# make installkernel
# reboot
# mergemaster -p # 建立臨時根環境並比對系統配置文件
# make installworld
# mergemaster
# 升級所有配置和其他文件# reboot
對於源的一些小改動,有時候簡單的命令就足夠了:
# make kernel world # 編譯並安裝內核和系統
# mergemaster
# reboot
磁盤信息 | Boot | 磁盤使用情況 | 已打開的文件 | 掛載/重掛 | 掛載
SMB | 掛載映像文件 | Burn
ISO | Create image | Memory
disk | Disk performance
權限
用 chmod
和 chown
更改訪問權限和所有權。對於所有用戶的默認掩碼(umask)可以在
/etc/profile (Linux) 或 /etc/login.conf (FreeBSD) 中修改。其默認掩碼(umask)通常爲 022。掩碼可以和777做減法,從而得到755的權限。
1 --x 執行 # Mode 764 = 執行/讀/寫 | 讀/寫 | 讀
2 -w- 寫
# |---所有者|---用戶組|---其他用戶|
4 r-- 讀
ugo=a u=所有者, g=用戶組, o=其他用戶, a=所有用戶
# chmod [OPTION] MODE[,MODE] FILE # MODE 可以是 [ugoa]*([-+=]([rwxXst]))
# chmod 640 /var/log/maillog
# 更改 maillog 訪問權限爲 -rw-r-----
# chmod u=rw,g=r,o= /var/log/maillog # 同上
# chmod -R o-r /home/*
# 遞歸去除所有其他用戶的可讀權限
# chmod u+s /path/to/prog # 在可執行位設置 SUID (知道你在幹什麼!當執行一個具有 setuid 權限的文件時,文件的執行過程將具有文件所有者的特權(比如root)。所以,應儘量避免不加選擇地創建和使用 root 用戶擁有的 seruid 程序或 root 組擁有的 setgid 程序。)
# find / -perm -u+s -print
# 查找所有設置過 SUID 位的程序
# chown user:group /path/to/file # 改變文件的所有者和文件關聯的組
# chgrp group /path/to/file
# 改變文件關聯的組
# chmod 640 `find ./ -type f -print` # Change permissions to 640 for all files
# chmod 751 `find ./ -type d -print`
# Change permissions to 751 for all directories
磁盤信息
# diskinfo -v /dev/ad2 # 顯示磁盤信息(扇區/大小) (FreeBSD)
# hdparm -I /dev/sda
# 顯示 IDE/ATA 磁盤信息 (Linux)
# fdisk /dev/ad2 # 顯示和修改磁盤分區表
# smartctl -a /dev/ad2
# 顯示磁盤檢測信息
Boot
FreeBSD
如果新內核不能引導,要引導一箇舊內核,停止啓動倒計時,做如下動作:
# unload
# load kernel.old
# boot
系統掛載點/磁盤使用情況
# mount | column -t # 顯示系統已掛載分區情況
# df
# 顯示磁盤剩餘空間和掛載的設備# cat /proc/partitions # 顯示所有設備的所有分區(Linux)
磁盤使用情況
# du -sh * # 列出當前目錄下所有文件夾大小
# du -csh
# 當前目錄下所有目錄大小總數
# du -ks * | sort -n -r # 由大到小排序顯示目錄大小
# ls -lSr
# 由小到大顯示文件列表
誰打開了那些文件
對於找出哪些文件阻止卸載分區並給出有代表性的錯誤是有幫助的:
# umount /home/
umount: unmount of /home # 不能卸載,因爲有一個文件鎖定了 home
failed: Device busy
FreeBSD 和大多數 Unix
# fstat -f /home # 對於一個掛載點
# fstat -p PID
# 對於一個應用程序進程 ID# fstat -u user # 對於一個用戶
查找已打開日誌文件(或其他已打開文件), 比如 Xorg:
# ps ax | grep Xorg | awk '{print $1}'
1252
# fstat -p 1252
USER CMD PID FD MOUNT INUM MODE SZ|DV R/W
root Xorg 1252 root / 2 drwxr-xr-x 512 r
root Xorg 1252 text /usr 216016 -rws--x--x 1679848 r
root Xorg 1252 0 /var 212042 -rw-r--r-- 56987 w
在 /var 中的只有一個 inum 爲 212042 的文件:
# find -x /var -inum 212042
/var/log/Xorg.0.log
Linux
使用 fuser
或 lsof
在一個掛載點中查找已打開的文件:
# fuser -m /home # 列出訪問 /home 的進程
# lsof /home
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
tcsh 29029 eedcoba cwd DIR 0,18 12288 1048587 /home/eedcoba (guam:/home)
lsof 29140 eedcoba cwd DIR 0,18 12288 1048587 /home/eedcoba (guam:/home)
關於一個應用程序:
ps ax | grep Xorg | awk '{print $1}'
3324
# lsof -p 3324
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
Xorg 3324 root 0w REG 8,6 56296 12492 /var/log/Xorg.0.log
關於單個文件:
# lsof /var/log/Xorg.0.log
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
Xorg 3324 root 0w REG 8,6 56296 12492 /var/log/Xorg.0.log
掛載/重掛載一個文件系統
舉個 cdrom 的例子。如果已經列於 /etc/fstab 中:
# mount /cdrom
或在 /dev/ 中查找設備,亦或使用 dmesg
命令
FreeBSD
# mount -v -t cd9660 /dev/cd0c /mnt # cdrom
# mount_cd9660 /dev/wcd0c /cdrom
# 另外一個方法# mount -v -t msdos /dev/fd0c /mnt # 軟驅
/etc/fstab 中的一條:
# Device Mountpoint FStype Options Dump Pass#
/dev/acd0 /cdrom cd9660 ro,noauto 0 0
要允許用戶做這些,可以這麼做:
# sysctl vfs.usermount=1 # 或者在 /etc/sysctl.conf 中插入一條 "vfs.usermount=1"
Linux
# mount -t auto /dev/cdrom /mnt/cdrom # 典型的 cdrom 掛載命令
# mount /dev/hdc -t iso9660 -r /cdrom
# IDE# mount /dev/sdc0 -t iso9660 -r /cdrom # SCSI
/etc/fstab 中的條目:
/dev/cdrom /media/cdrom subfs noauto,fs=cdfss,ro,procuid,nosuid,nodev,exec 0 0
用 Linux 掛載一個 FreeBSD 分區
用 fdisk 查找分區號,這通常是 root 分區,但也可能是其他 BSD slice。如果 FreeBSD 有許多 slice,他們不列於同一個 fdisk 分區表中,但可見於 /dev/sda* 或 /dev/hda* 中。
# fdisk /dev/sda # 查找 FreeBSD 分區
/dev/sda3 * 5357 7905 20474842+ a5 FreeBSD
# mount -t ufs -o ufstype=ufs2,ro /dev/sda3 /mnt
/dev/sda10 = /tmp; /dev/sda11 /usr
# 其他 slice
重掛載
不用卸載一個設備來重掛載。 對 fsck
來說是必須的。舉個例子:
# mount -o remount,ro / # Linux
# mount -o ro /
# FreeBSD
從 cdrom 拷貝原始數據進一個 iso 映像文件:
# dd if=/dev/cd0c of=file.iso
給即時燒錄(on-the-fly)添加 swap
假設你需要很多的 swap (即刻),如一個 2GB 文件 /swap2gb (只限 Linux)。
# dd if=/dev/zero of=/swap2gb bs=1024k count=2000
# mkswap /swap2gb # 創建交換區
# swapon /swap2gb
# 激活這個 swap。現在可以使用了
# swapoff /swap2gb # 當使用完畢,釋放這個 swap
# rm /swap2gb
掛載一個 SMB譯註:SMB (Server Message Block,服務器信息塊),又稱 CIFS (Common Internet File System,通用Internet文件系統) 共享
假 設我們要訪問計算機 smbserver 上的名叫 myshare 的 SMB 共享,在 window PC 上鍵入的地址是 \\smbserver\myshare\。我掛載到 /mnt/smbshare 上。注意 cifs 必須是 IP 或 DNS 名,不是 Windows 名字。
Linux
# smbclient -U user -I 192.168.16.229 -L //smbshare/ # 列出共享
# mount -t smbfs -o username=winuser //smbserver/myshare /mnt/smbshare
# mount -t cifs -o username=winuser,password=winpwd //192.168.16.229/myshare /mnt/share
此外,mount.cifs 軟件包可以存儲認證到一個文件中。例如,/home/user/.smb
:
username=winuser
password=winpwd
現在可以像下面那樣掛載:
# mount -t cifs -o credentials=/home/user/.smb //192.168.16.229/myshare /mnt/smbshare
FreeBSD
使用 -I 來獲取 IP (或 DNS 名);smbserver 是 Windows 名。
# smbutil view -I 192.168.16.229 //winuser@smbserver # 列出共享
# mount_smbfs -I 192.168.16.229 //winuser@smbserver/myshare /mnt/smbshare
掛載鏡像文件
Linux loop-back
# mount -t iso9660 -o loop file.iso /mnt # 掛載 CD 鏡像文件
# mount -t ext3 -o loop file.img /mnt
# 用 ext3 文件系統掛載鏡像文件
FreeBSD
用於存儲設備 (如果需要做 # kldload md.ko 動作):
# mdconfig -a -t vnode -f file.iso -u 0
# mount -t cd9660 /dev/md0 /mnt
# umount /mnt; mdconfig -d -u 0 # 清除 md 設備
用於虛擬節點:
# vnconfig /dev/vn0c file.iso; mount -t cd9660 /dev/vn0c /mnt
# umount /mnt; vnconfig -u /dev/vn0c # 清除 vn 設備
Solaris and FreeBSD
用於 loop-back 文件接口或 lofi:
# lofiadm -a file.iso
# mount -F hsfs -o ro /dev/lofi/1 /mnt
# umount /mnt; lofiadm -d /dev/lofi/1 # 清除 lofi 設備
創建並刻錄 ISO 鏡像文件
這將會拷貝 CD 或者 DVD 的扇區。當不用 conv=notrunc
,鏡像文件會等於 CD 內容大小而非 CD 容量大小。看下面和 dd
例子。
# dd if=/dev/hdc of=/tmp/mycd.iso bs=2048 conv=notrunc
使用 mkisofs 把目錄中所有文件創建成 CD/DVD 鏡像文件。克服文件名限制:-r 開啓 Rock Ridge 擴展用於 Unix 系統,-J 開啓 Joliet 擴展用於微軟系統。-L 允許 ISO9660 文件名第一個字符爲句點。
# mkisofs -J -L -r -V TITLE -o imagefile.iso /path/to/dir
對於 FreeBSD,mkisofs 可以到 port 的 sysutils/cdrtools 中找到。
刻錄 ISO 鏡像文件
FreeBSD
FreeBSD 默認情況下沒有在 ATAPI 驅動上啓用 DMA。DMA 可用 sysctl 命令啓用,其參數如下,或者在 /boot/loader.conf 中添加如下條目:
hw.ata.ata_dma="1"
hw.ata.atapi_dma="1"
burncd
用於 ATAPI 驅動(burncd
爲基本系統的一部分),cdrecord
(在
sysutils/cdrtools 中)用於 SCSI 驅動。
# burncd -f /dev/acd0 data imagefile.iso fixate # ATAPI 驅動
# cdrecord -scanbus
# 查找 burner 設備描述符(如 1,0,0)# cdrecord dev=1,0,0 imagefile.iso
Linux
對於 Linux,同樣使用 cdrecord
如上文所述。此外,它還可以使用本地 ATAPI 接口查找設備描述符:
# cdrecord dev=ATAPI -scanbus
然後同上面一樣燒錄 CD/DVD。
dvd+rw-tools
dvd+rw-toolshttp://fy.chalmers.se/~appro/linux/DVD+RW/ 工具包(FreeBSD: ports/sysutils/dvd+rw-tools)可以做上面的一切,其還包括
growisofs 工具來刻錄 CD 或 DVD。本實例所引用的 DVD 設備 /dev/dvd
可能是指向 /dev/scd0
(Linux)的符號連接,或者 /dev/cd0
(FreeBSD),或者 /dev/rcd0c
(NetBSD/OpenBSD),或者 /dev/rdsk/c0t1d0s2
(Solaris)。對於本實例 FreeBSD
手冊 18.7 章http://www.freebsd.org/handbook/creating-dvds.html 上有一份很好的文檔。
# -dvd-compat 選項將完結光盤,光盤便不可再附加數據
# growisofs -dvd-compat -Z /dev/dvd=imagefile.iso
# 刻錄已存在的 iso 鏡像文件# growisofs -dvd-compat -Z /dev/dvd -J -R /p/to/data # 直接刻錄
轉換 Nero .nrg 文件成 .iso
Nero 簡單的添加了 300KB 的頭到一個常規的 iso 鏡像文件中。我們可用 dd 工具來去除它。
# dd bs=1k if=imagefile.nrg of=imagefile.iso skip=300
轉換 bin/cue 鏡像成 .iso
bchunk
程序http://freshmeat.net/projects/bchunk/可以做到這一點。在
FreeBSD 中,它在 port 的 sysutils/bchunk 中。
# bchunk imagefile.bin imagefile.cue imagefile.iso
創建基於文件的鏡像文件
舉個例子,一個使用文件 /usr/vdisk.img 的 1GB 分區。這裏我們使用 vnode 0,但也可爲 1。
FreeBSD
# dd if=/dev/random of=/usr/vdisk.img bs=1K count=1M
# mdconfig -a -t vnode -f /usr/vdisk.img -u 0 # 創建設備 /dev/md1
# bsdlabel -w /dev/md0
# newfs /dev/md0c
# mount /dev/md0c /mnt
# umount /mnt; mdconfig -d -u 0; rm /usr/vdisk.img
# 清除 md 設備
這個基於文件的鏡像文件可以在 /etc/rc.conf 和 /etc/fstab 中配置成啓動期間自動掛載。可用 # /etc/rc.d/mdconfig start
(先用 #
mdconfig -d -u 0
命令刪除 md0 設備) 測試你的設置。
需 要注意的是,那個自動設置僅工作於這個基於文件的鏡像文件不在 root 分區中。原因是 /etc/rc.d/mdconfig 腳本早於啓動就執行了,並且 root 分區仍然是隻讀的。腳本 /etc/rc.d/mdconfig2 之後,鏡像文件將位於 root 分區外掛載。
/boot/loader.conf:
md_load="YES"
/etc/rc.conf:
# mdconfig_md0="-t vnode -f /usr/vdisk.img" # /usr 不在 root 分區中
/etc/fstab: (行後的兩個 0 0 很重要,它告訴 fsck 忽略這個設備,現在還不存在。)
/dev/md0 /usr/vdisk ufs rw 0 0
也可能在增加鏡像文件的大小之後,如增大到 300MB。
# umount /mnt; mdconfig -d -u 0
# dd if=/dev/zero bs=1m count=300 >> /usr/vdisk.img
# mdconfig -a -t vnode -f /usr/vdisk.img -u 0
# growfs /dev/md0
# mount /dev/md0c /mnt # 文件分區現在爲 300MB
Linux
# dd if=/dev/zero of=/usr/vdisk.img bs=1024k count=1024
# mkfs.ext3 /usr/vdisk.img
# mount -o loop /usr/vdisk.img /mnt
# umount /mnt; rm /usr/vdisk.img # 清楚
Linux with losetup
/dev/zero
比 urandom
更快,但對於加密來說卻不夠安全。
# dd if=/dev/urandom of=/usr/vdisk.img bs=1024k count=1024
# losetup /dev/loop0 /usr/vdisk.img # 創建並聯結 /dev/loop0
# mkfs.ext3 /dev/loop0
# mount /dev/loop0 /mnt
# losetup -a
# 查看已經掛載的 loop 設備
# umount /mnt
# losetup -d /dev/loop0 # Detach
# rm /usr/vdisk.img
創建基於內存的文件系統
基於內存的文件系統對於重量級 IO 應用程序來說非常快。怎樣創建一個掛載到 /memdisk 的 64M 分區:
FreeBSD
# mount_mfs -o rw -s 64M md /memdisk
# umount /memdisk; mdconfig -d -u 0 # 清除該 md 設備
md /memdisk mfs rw,-s64M 0 0
# /etc/fstab 條目
Linux
# mount -t tmpfs -osize=64m tmpfs /memdisk
磁盤性能
在 ad4s3c (/home) 分區上讀寫一個 1GB 的文件。
# time dd if=/dev/ad4s3c of=/dev/null bs=1024k count=1000
# time dd if=/dev/zero bs=1024k count=1000 of=/home/1Gb.file
# hdparm -tT /dev/hda # 僅限 Linux
路由 | 額外
IP | 更改 MAC 地址 | 端口 | 防火牆 | IP
轉發 | NAT | DNS | DHCP | 通信量 | QoS | NIS
Linux
# ethtool eth0 # 顯示以太網狀態(replaces mii-diag)
# ethtool -s eth0 speed 100 duplex full
# 把網卡 eth0 速度改爲 100兆/秒,採用全雙工
# ethtool -s eth0 autoneg off # 禁用自動協商模式
# ethtool -p eth1
# 閃爍網絡接口 LED 燈 - 如果支持的話,非常實用
# ip link show # 在 Linux 上顯示所有網絡接口(同 ifconfig 類似)
# ip link set eth0 up
# 使設備激活(或Down掉)。同 "ifconfig eth0 up"
# ip addr show # 在 Linux 上顯示所有 IP 地址(與 ifconfig 類似)
# ip neigh show
# 與 arp -a 類似
其他系統
# ifconfig fxp0 # 查看 "media" 字段(FreeBSD)
# arp -a
# 查看路由(或主機) ARP 條目(所有系統)
# ping cb.vu # 第一個要試的事情...
# traceroute cb.vu
# 列印到目的地的路由路徑
# ifconfig fxp0 media 100baseTX mediaopt full-duplex # 100兆/秒 全雙工(FreeBSD)
# netstat -s
# 對每個網絡協議做系統級分析
另一些命令,雖然不總是默認安裝,但很好找:
# arping 192.168.16.254 # 在網絡層上 Ping
# tcptraceroute -f 5 cb.vu
# 使用 tcp 替換 icmp 來跟蹤,透過防火牆
路由
列印路由表
# route -n # Linux 或使用 "ip route"
# netstat -rn
# Linux, BSD 和 UNIX# route print # Windows
添加刪除路由
FreeBSD
# route add 212.117.0.0/16 192.168.1.1
# route delete 212.117.0.0/16
# route add default 192.168.1.1
永久的添加路由可在 /etc/rc.conf 配置文件中設置
static_routes="myroute"
route_myroute="-net 212.117.0.0/16 192.168.1.1"
Linux
# route add -net 192.168.20.0 netmask 255.255.255.0 gw 192.168.16.254
# ip route add 192.168.20.0/24 via 192.168.16.254 # 等同於上面命令
# route add -net 192.168.20.0 netmask 255.255.255.0 dev eth0
# route add default gw 192.168.51.254
# ip route add default via 192.168.51.254 dev eth0
# 等同於上面命令# route delete -net 192.168.20.0 netmask 255.255.255.0
Solaris
# route add -net 192.168.20.0 -netmask 255.255.255.0 192.168.16.254
# route add default 192.168.51.254 1 # 1 = 通過此路由跳譯註:數據包生存週期依賴於 IP 頭中的生存週期(Time-to-Live,簡稱 TTL)。根據 RFC 的定義,這個域值由每個路由器來減少。接收到包的每臺路由器根據路由該包所花費的秒數,將包中的這個域值減去相應的時間,或直接減 1。因爲目前路由器轉發包的時間基本小於 1 秒,這個域值基本上在源和目的地之間的沒一跳便會減 1。數減 1
# route change default 192.168.50.254 1
永久條目配置在 /etc/defaultrouter
中。
Windows
# Route add 192.168.50.0 mask 255.255.255.0 192.168.51.253
# Route add 0.0.0.0 mask 0.0.0.0 192.168.51.254
使用 add -p
來是路由設置永久有效。
配置額外的 IP 地址
Linux
# ifconfig eth0 192.168.50.254 netmask 255.255.255.0 # 第一個 IP
# ifconfig eth0:0 192.168.51.254 netmask 255.255.255.0
# 第二個 IP
# ip addr add 192.168.50.254/24 dev eth0 # 等價命令
# ip addr add 192.168.51.254/24 dev eth0 label eth0:1
FreeBSD
# ifconfig fxp0 inet 192.168.50.254/24 # 第一個 IP
# ifconfig fxp0 alias 192.168.51.254 netmask 255.255.255.0
# 第二個 IP
永久條目設置在 /etc/rc.conf 中
ifconfig_fxp0="inet 192.168.50.254 netmask 255.255.255.0"
ifconfig_fxp0_alias0="192.168.51.254 netmask 255.255.255.0"
Solaris
用 ifconfig -a
命令檢查設置
# ifconfig hme0 plumb # 啓用網卡
# ifconfig hme0 192.168.50.254 netmask 255.255.255.0 up
# 第一個 IP# ifconfig hme0:1 192.168.51.254 netmask 255.255.255.0 up # 第二個 IP
更改 MAC 地址
通常在你更改之前先停下網絡接口。不要告訴我爲什麼你想改變 MAC 地址......
# ifconfig eth0 down
# ifconfig eth0 hw ether 00:01:02:03:04:05 # Linux
# ifconfig fxp0 link 00:01:02:03:04:05
# FreeBSD
# ifconfig hme0 ether 00:01:02:03:04:05 # Solaris
# sudo ifconfig en0 ether 00:01:02:03:04:05
# Mac OS X Tiger# sudo ifconfig en0 lladdr 00:01:02:03:04:05 # Mac OS X Leopard
對於 Windows 已經有許多工具了。像 etherchangehttp://ntsecurity.nu/toolbox/etherchange。或者看看
"Mac Makeup", "smac"。
使用中的端口
監聽打開的端口:
# netstat -an | grep LISTEN
# lsof -i # 列出所有因特網連接(Linux)
# socklist
# 列出打開的 socket (Linux)
# sockstat -4 # 使用 socket 的應用程序列表(FreeBSD)
# netstat -anp --udp --tcp | grep LISTEN
# Linux
# netstat -tup # 列出活躍的連接(Linux)
# netstat -tupl
# 列出系統中正在監聽的端口(Linux)# netstat -ano # Windows
防火牆
檢查正在運行的防火牆(只是典型配置):
Linux
# iptables -L -n -v # 狀態信息
Open the iptables firewall
# iptables -P INPUT ACCEPT
# 打開所有
# iptables -P FORWARD ACCEPT
# iptables -P OUTPUT ACCEPT
# iptables -Z # 把所有鏈的包及字節的計數器清空
# iptables -F
# 清空所有鏈# iptables -X # 刪除所有鏈譯註:鏈必須沒有被引用
FreeBSD
# ipfw show # 狀態信息
# ipfw list 65535
# 如果顯示 "65535 deny ip from any to any",那防火牆已被禁用
# sysctl net.inet.ip.fw.enable=0 # 禁用
# sysctl net.inet.ip.fw.enable=1
# 啓用
路由 IP 轉發
Linux
查看然後啓用 IP 轉發:
# cat /proc/sys/net/ipv4/ip_forward # 查看 IP 轉發 0=禁用, 1=啓用
# echo 1 > /proc/sys/net/ipv4/ip_forward
或者編輯 /etc/sysctl.conf:
net.ipv4.ip_forward = 1
FreeBSD
查看並啓用:
# sysctl net.inet.ip.forwarding # 查看 IP 轉發 0=禁用, 1=啓用
# sysctl net.inet.ip.forwarding=1
# sysctl net.inet.ip.fastforwarding=1
# 專用路由器或防火牆
Permanent with entry in /etc/rc.conf:
gateway_enable="YES" # 如果主機是網關則設置爲 YES。
Solaris
# ndd -set /dev/ip ip_forwarding 1 # 查看 IP 轉發 0=禁用, 1=啓用
NAT - 網絡地址轉換
Linux
# iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE # 激活 NAT
# iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 20022 -j DNAT --to 192.168.16.44:22
# 轉發端口 20022 到內部 IP 端口(ssh)
# iptables -t nat -A PREROUTING -p tcp -d 78.31.70.238 --dport 993:995 -j DNAT --to 192.168.16.254:993:995 # 轉發 993-995 範圍端口
# ip route flush cache
# iptables -L -t nat
# 查看 NAT 狀態信息
使用 -D 替換 -A 來刪除端口轉發。
FreeBSD
# natd -s -m -u -dynamic -f /etc/natd.conf -n fxp0
Or edit /etc/rc.conf with:
firewall_enable="YES" # 設置 YES 來啓用防火牆功能
firewall_type="open"
# 防火牆類型(看 /etc/rc.firewall)
natd_enable="YES" # 啓用 natd (如果 firewall_enable == YES)。
natd_interface="tun0"
# 公共的網絡接口或要使用的 IP 地址。natd_flags="-s -m -u -dynamic -f /etc/natd.conf"
端口轉發:
# cat /etc/natd.conf
same_ports yes
use_sockets yes
unregistered_only
# redirect_port tcp insideIP:2300-2399 3300-3399 # 端口範圍
redirect_port udp 192.168.51.103:7777 7777
DNS
在 unix 上,對於所有的網絡接口的 DNS 條目都存儲在 /etc/resolv.conf 文件中。主機域也儲存在這個文件中。最小化配置如下:
nameserver 78.31.70.238
search sleepyowl.net intern.lab
domain sleepyowl.net
檢查系統域名:
# hostname -d # 等同於 dnsdomainname
Windows
在 Windows 上,DNS 配置於每個網絡接口。要顯示配置的 DNS 和清空 DNS 緩存可是使用:
# ipconfig /? # 顯示幫助
# ipconfig /all
# 顯示所有信息包括 DNS# ipconfig /flushdns # 清除 DNS 緩存
轉發查詢
Dig 是你測試 DNS 設置的好朋友。舉個例子,用於測試的 DNS 服務器爲 213.133.105.2 ns.second-ns.de
。查看哪個服務器客戶端接收應答(簡單應答).
# dig sleepyowl.net
sleepyowl.net. 600 IN A 78.31.70.238
;; SERVER: 192.168.51.254#53(192.168.51.254)
路由器 192.168.51.254 應答了,並返回了一條 A 條目(記錄)。任何條目都可查詢,DNS 服務器可用 @ 來選定:
# dig MX google.com
# dig @127.0.0.1 NS sun.com # 測試本地服務器
# dig @204.97.212.10 NS MX heise.de
# 查詢外部# dig AXFR @ns1.xname.org cb.vu # 查看區傳送(zone transfer)
程式 host 也很強大。
# host -t MX cb.vu # 獲取郵件 MX 記錄
# host -t NS -T sun.com
# 通過 TCP 連接獲取 NS 記錄# host -a sleepyowl.net # 獲取所有
反向查詢
查找屬於一個 IP 地址(in-addr.arpa.)的域名。可用 dig
, host
和 nslookup
命令查詢:
# dig -x 78.31.70.238
# host 78.31.70.238
# nslookup 78.31.70.238
/etc/hosts
單個主機可以配置於文件 /etc/hosts 來代替本地正在運行的 named
反向域名查詢。格式很簡單,舉個例子:
78.31.70.238 sleepyowl.net sleepyowl
對於 hosts 文件和 DNS 查詢之間的優先級,可在 /etc/nsswitch.conf
和 /etc/host.conf
中配置
order 名稱解析。這個文件同樣存在於 Windows 上,通常在:
C:\WINDOWS\SYSTEM32\DRIVERS\ETC
DHCP
Linux
一些發行版(SuSE)使用 dhcpcd 作爲客戶端。默認網絡接口是 eth0。
# dhcpcd -n eth0 # 觸發更新(並不總是可以工作)
# dhcpcd -k eth0
# 釋放並關閉
租約(lease)的全部信息存儲在:
/var/lib/dhcpcd/dhcpcd-eth0.info
FreeBSD
FreeBSD (和 Debian) 使用 dhclient
。要配置一個網絡接口(如:bge0)運行:
# dhclient bge0
租約(lease)的全部信息存儲在:
/var/db/dhclient.leases.bge0
使用
/etc/dhclient.conf
設置 prepend 選項或強制不同的選項:
# cat /etc/dhclient.conf
interface "rl0" {
prepend domain-name-servers 127.0.0.1;
default domain-name "sleepyowl.net";
supersede domain-name "sleepyowl.net";
}
Windows
dhcp 租約(lease)使用 ipconfig
來更新:
# ipconfig /renew # 更新所有適配器
# ipconfig /renew LAN
# 更新名叫 "LAN" 的適配器# ipconfig /release WLAN # 釋放名叫 "WLAN" 的適配器
是的,這是一個使用簡單名稱重新命名你的適配器的好主意!
通信量分析(Traffic analysis)
Bmonhttp://people.suug.ch/~tgr/bmon/ 是一個小的流量監控控制檯,而且可以顯示不同的網絡接口的流量。
用 tcpdump 嗅探(sniff)
# tcpdump -nl -i bge0 not port ssh and src 192.168.16.121or192.168.16.54
# tcpdump -l > dump && tail -f dump # 緩衝輸出
# tcpdump -i rl0 -w traffic.rl0
# 把數據報文寫入二進制文件
# tcpdump -r traffic.rl0 # 從文件讀取數據報文(也可以使用 ethereal)
# tcpdump port 80
# 兩個經典命令
# tcpdump host google.com
# tcpdump -i eth0 -X port 110or143
# 查看端口 110(POP) 或 143(IMAP)的數據報文
# tcpdump -n -i eth0 icmp
# 只捕獲 ping# tcpdump -i eth0 -s 0 -A port 80 | grep GET # -s 0 爲全部包, -A 爲 ASCII
另一些重要選項:
-A
顯示每個包清晰文本(除了報頭)-X
顯示包的 ASCII 文本-l
使標準輸出變爲緩衝行形式-D
顯示所有可用網絡接口
對於 Windows 可以使用 www.winpcap.org。使用 windump -D 來列出網絡接口。
用 nmap 掃描
Nmaphttp://insecure.org/nmap/ 是一個用於 OS 探測的端口掃描工具,她通常在許多發行版上有安裝,並且同樣可用於 Windows。如果你不掃描你的服務器,駭客們會爲你做這些...
# nmap cb.vu # 掃描主機上所有保留的 TCP 端口
# nmap -sP 192.168.16.0/24
# 找出在 0/24 上主機所使用的 IP譯註:通過使用 "-sP" 參數,進行 ping 掃描。缺省情況下,Nmap給每個掃描到的主機發送一個 ICMP echo 和一個 TCP ACK,主機對任何一種的響應都會被Nmap得到。
# nmap -sS -sV -O cb.vu # 做祕密 SYN 掃描來探測系統和系統服務的版本信息
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 3.8.1p1 FreeBSD-20060930 (protocol 2.0)
25/tcp open smtp Sendmail smtpd 8.13.6/8.13.6
80/tcp open http Apache httpd 2.0.59 ((FreeBSD) DAV/2 PHP/4.
[...]
Running: FreeBSD 5.X
Uptime 33.120 days (since Fri Aug 31 11:41:04 2007)
其他非標準但好用的工具有 hping
(www.hping.org),她是一個 IP 分組組裝/分析器,和 fping
(fping.sourceforge.net)。fping
可以在一個循環隊列(round-robin fashion)中掃描多種主機。
流量控制(QoS)
流量控制管理着一個網絡的隊列、流量監控、調度以及其他流量設置(traffic parameters)。以下簡單實用的示例使用 Linux 和 FreeBSD 的能力來更好的利用帶寬。
上傳限制
DSL 或有線調制解調器有一個很長的列隊來提高上傳吞吐量(upload throughput)。然而用一個快速的設備(如以太網)填充這個列隊將大大減少交互性。這就是限制設備上傳速度有用的原因,以匹配調制解調器的實際能 力,這可以有效提高交互性。設置大約爲 modem 最大速度的 90%。
Linux
給 512K 上傳速度的 modem。
# tc qdisc add dev eth0 root tbf rate 480kbit latency 50ms burst 1540
# tc -s qdisc ls dev eth0 # 狀態
# tc qdisc del dev eth0 root
# 刪除隊列# tc qdisc change dev eth0 root tbf rate 220kbit latency 50ms burst 1540
FreeBSD
FreeBSD 使用 dummynet
來控制帶寬,其配置工具爲 ipfw。Pipe 用來設置限制帶寬的單位[K|M]{比特/秒|字節/秒},0 意味着沒有限制。使用同樣的 pipe 數字可重新配置它。舉個例子,限制上傳帶寬爲 500K。
# kldload dummynet # 如有必要加載這個模塊
# ipfw pipe 1 config bw 500Kbit/s
# 創建一個帶寬限制的 pipe# ipfw add pipe 1 ip from me to any # 轉移所有上傳進入這個 pipe
服務質量 (Quality of service)
Linux
使用 tc
的優先級隊列來優化 VoIP。在 voip-info.org 或 www.howtoforge.com 上可以看到完整的例子。假設
VoIP 使用 UDP 端口 10000:11024 並且使用 eth0 設備(也可爲 ppp0 或 so)。下列命令定義了三個隊列,並且用 QoS 0x1e
(設置所有位) 強制 VOIP 流量到隊列 1。默認流量流入隊列 3,Qos Minimize-Delay 流入隊列 2。
# tc qdisc add dev eth0 root handle 1: prio priomap 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 0
# tc qdisc add dev eth0 parent 1:1 handle 10: sfq
# tc qdisc add dev eth0 parent 1:2 handle 20: sfq
# tc qdisc add dev eth0 parent 1:3 handle 30: sfq
# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 10000 0x3C00 flowid 1:1 # 使用服務端端口範圍
match ip dst 123.23.0.1 flowid 1:1
# 或/和使用服務器 IP
狀態和移除:
# tc -s qdisc ls dev eth0 # queue status
# tc qdisc del dev eth0 root
# delete all QoS
計算端口範圍和掩碼 (mask)
用你所計算的端口掩碼來定義 tc 過濾器的端口範圍。查詢 2^N 端口範圍結尾,推斷範圍並轉換成十六進制。這就是你的掩碼 (mask)。例如 10000 -> 11024,它的範圍是 1024。
# 2^13 (8192) < 10000 < 2^14 (16384) # 結尾是 2^14 = 16384
# echo "obase=16;(2^14)-1024" | bc
# 掩碼是 0x3C00
FreeBSD
假設最大連接帶寬爲 500Kbit/s,我們使用優先級 100:10:1 定義 3 個隊列給 VoIP:ssh:剩餘所有。
# ipfw pipe 1 config bw 500Kbit/s
# ipfw queue 1 config pipe 1 weight 100
# ipfw queue 2 config pipe 1 weight 10
# ipfw queue 3 config pipe 1 weight 1
# ipfw add 10 queue 1 proto udp dst-port 10000-11024
# ipfw add 11 queue 1 proto udp dst-ip 123.23.0.1 # 或/和使用服務器 IP
# ipfw add 20 queue 2 dsp-port ssh
# ipfw add 30 queue 3 from me to any
# 剩餘所有
狀態和移除:
# ipfw list # 規則信息
# ipfw pipe list
# 管道信息# ipfw flush # 刪除除默認外所有規則
NIS 調試
一些可工作在已配置好的 NIS 客戶端上的命令:
# ypwhich # 獲取提供 NIS 服務的服務器名
# domainname
# 已配置的 NIS 域名
# ypcat group # 列印 NIS 映射 group
# cd /var/yp && make
# 重建 yp 數據庫
ypbind 正在運行嗎?
# ps auxww | grep ypbind
/usr/sbin/ypbind -s -m -S servername1,servername2 # FreeBSD
/usr/sbin/ypbind
# Linux
# yppoll passwd.byname
Map passwd.byname has order number 1190635041. Mon Sep 24 13:57:21 2007
The master server is servername.domain.net.
Linux
# cat /etc/yp.conf
ypserver servername
domain domain.net broadcast
公鑰認證 | 指紋 | SCP | 隧道(Tunneling)
Public key authentication
使用公鑰認證而不是密碼連接主機。方法是附加你的公鑰文件到遠程主機。本例中我們用客戶端產生的 key 從 host-client 連接到 host-server。
- 使用 ssh-keygen 生成密鑰對。私鑰放在
~/.ssh/id_dsa
,公鑰在 ~/.ssh/id_dsa.pub
。 - 拷貝你的公鑰到服務器的
~/.ssh/authorized_keys2
。
# ssh-keygen -t dsa -N ''
# cat ~/.ssh/id_dsa.pub | ssh you@host-server "cat - >> ~/.ssh/authorized_keys2"
使用來自 ssh.com 的 Windows 客戶端
ssh.com 的非商業性版本的客戶端可下載自它主 FTP 站點:ftp.ssh.com/pub/ssh/。 用 ssh.com
客戶端產生的密鑰需要在 OpenSSH 服務器上進行轉換。可以使用 ssh-keygen 命令來完成。
- 使用 ssh.com 客戶端創建一對密鑰:Settings - User Authentication - Generate New....
- 我使用 DSA 密鑰類型;密鑰長度爲 2048。
- 拷貝 ssh.com 客戶端產生的公鑰到服務器的 ~/.ssh 目錄。
- 她的密鑰對在 C:\Documents and Settings\%USERNAME%\Application Data\SSH\UserKeys。
- 在服務器上使用 ssh-keygen 轉換公鑰:
# cd ~/.ssh
# ssh-keygen -i -f keyfilename.pub >> authorized_keys2
注意: 我們使用 DSA 密鑰,使用 RSA 密鑰也是可以的。這個密鑰不受密碼保護。
在 Windows 上使用 Putty
Puttyhttp://www.chiark.greenend.org.uk/~sgtatham/putty/download.html
是一個簡單並且自由的(MIT許可)譯註:free 不單單是免費 ssh Windows 客戶端。
- 使用 puTTYgen 程序創建密鑰對。
- 保存密鑰對(比如:C:\Documents and Settings\%USERNAME%\.ssh).
- 拷貝公鑰到服務器的 ~/.ssh 目錄:
- 使用 ssh-keygen 在 OpenSSH 服務器上轉換這個公鑰:
# cd ~/.ssh
# ssh-keygen -i -f puttykey.pub >> authorized_keys2
- 在 Putty 中設置指向私鑰的位置:Connection - SSH - Auth
檢查指紋
在首次連接時,SSH 會請求保存不知道的主機指紋。要避免中間人(man-in-the-middle)攻擊,服務器的管理員可以發送密鑰指紋給客戶端,來讓其在首次登陸時驗證服務器的真實性。使用 ssh-keygen -l
獲取服務器的指紋:
# ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key.pub # RSA 密鑰
2048 61:33:be:9b:ae:6c:36:31:fd:83:98:b7:99:2d:9f:cd /etc/ssh/ssh_host_rsa_key.pub
# ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key.pub
# DSA 密鑰(默認)2048 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee /etc/ssh/ssh_host_dsa_key.pub
現在客戶端在連接到服務器時可驗證其服務器的真實性:
# ssh linda
The authenticity of host 'linda (192.168.16.54)' can't be established.
DSA key fingerprint is 14:4a:aa:d9:73:25:46:6d:0a:48:35:c7:f4:16:d4:ee.
Are you sure you want to continue connecting (yes/no)? yes
安全文件傳輸
一些簡單的命令:
# scp file.txt host-two:/tmp
# scp joe@host-two:/www/*.html /www/tmp
# scp -r joe@host-two:/www /www/tmp
在 Konqueror 或 Midnight 控制檯中,用地址 fish://user@gate 來訪問遠程文件系統是可行的,就是比較慢而已。
此外,也可以用基於 SCP 文件系統客戶端的 sshfs 來掛載一個遠程目錄。看 fuse sshfshttp://fuse.sourceforge.net/sshfs.html.
隧道(Tunneling)
SSH 隧道可以讓你通過 SSH 連接進行端口轉發(轉發/反向隧道),從而確保了傳輸及端口訪問的安全。它只能工作在 TCP 協議上。通常端口轉發命令如下(也可看 ssh
和 NAT 實例):
# ssh -L localport:desthost:destport user@gate # gate 爲目標主機網關
# ssh -R destport:desthost:localport user@gate
# 轉發你的 localport 到目標端口# ssh -X user@gate # 轉發 X 程序
這將會連接到 gate 並轉發端口到目標主機 desthost:destport。注意 desthost 爲 gate 中的目標主機名。因此,如果連接到了 gate,那麼 desthost 就是 localhost。也可以做更多的端口轉發。
在 gate 上直接轉發
假 設我們想訪問在 gate 上運行的 CVS(2401端口) 和 HTTP(80端口)。下面是個簡單的例子,desthost 就是 localhost,我們使用本的端口 8080 代替 80 端口,所以我們不需要 root 權限。一旦 ssh session 打開,二個服務就都可在本地端口訪問。
# ssh -L 2401:localhost:2401 -L 8080:localhost:80 user@gate
轉發 Netbios 和遠程桌面到第二個服務器
假設有一臺在 gate 後面沒有運行 ssh 的 Winodws SMB 服務器。我們需要訪問 SMB 共享和遠程桌面。
# ssh -L 139:smbserver:139 -L 3388:smbserver:3389 user@gate
現在這個 SMB 共享可以使用 \\127.0.0.1\ 訪問,但只能在本地共享關閉的情況下,因爲本的共享也是在 139 端口監聽的。
保持本的共享也是可行的,因此我們需要爲這個通道使用新 IP 地址來新建一個虛擬設備,SMB 共享將會使用此地址連接。此外,本地 RDP 已經在 3389 端口監聽了,所以我們選擇端口 3388。對於這個例子,讓我們使用一個虛擬 IP 地址 10.1.1.1。
- 對於 Putty 上使用源端口=10.1.1.1:139。它可以創建多重回路(multiple loop)設備和通道。在 Windows 2000 上,只有 Putty 爲我工作。
- 對於 ssh.com 的客戶端,要禁用 "Allow local connections only"。因爲 ssh.com 客戶端綁定了所有地址,所以只能連接單個共享。
現在用 IP 地址 10.1.1.1 創建迴路(loopback)接口:
- # 系統->控制面板->添加硬件 # 是,我已經連接了此硬件(Y) # 添加新的硬件設備(在列表最下面)。
- # 安裝我手動選擇的硬件 # 網絡適配器 # Microsoft , Microsoft Loopback Adapter。
- 配置這個假設備的 IP 地址爲 10.1.1.1,掩碼 255.255.255.0,沒有網關。
- 高級->WINS,開啓 LMHOSTS 查詢;禁用 TCP/IP 上的 NetBIOS。
- # 啓用 Microsoft 網絡客戶端。# 禁用 Microsoft 網絡文件和打印機共享
做完這些之後我有重啓。現在用 \\10.1.1.1 連接 SMB 共享和用 10.1.1.1:3388 連接遠程桌面。
調試
如果不能工作:
- 端口有沒有轉發:運行控制檯運行 netstat -an 命令並查看有沒有 0.0.0.0:139 或者 10.1.1.1:139
- 有沒有 telnet 到 10.1.1.1 139?
- 你需要打開 "本地端口接受其他主機連接"。
- "Microsoft 網絡文件和打印機共享" 有沒有被禁用?
在 NAT 後面連接兩個客戶端
假 設兩個客戶端在一個 NAT 網關後面,cliadmin 客戶端要連接到 cliuser 客戶端(目的地),兩者都可用 ssh 登錄到正在運行 sshd 的 gate 上。你不需要 root 權限,只要端口大於 1024 即可。我們在 gate 上使用 2022 端口。而且,由於 gate 使用與本地,所以網關端口不是必須的。
開啓 cliuser 客戶端(從目標到 gate):
# ssh -R 2022:localhost:22 user@gate # 轉發客戶端 22 端口到 gate:2022 端口
開啓 cliadmin 客戶端(從主機到 gate):
# ssh -L 3022:localhost:2022 admin@gate # 轉發客戶端 3022 端口到 gate:2022 端口
現在 admin 可以直接連接 cliuser 客戶端:
# ssh -p 3022 admin@localhost # local:3022 -> gate:2022 -> client:22
在 NAT 後面的 VNC 連接
假設一個在 NAT 後面,監聽在端口 5900 上可被訪問的 Windows VNC 客戶端。
開啓 cliwin 客戶端到 gate:
# ssh -R 15900:localhost:5900 user@gate
開啓 cliadmin 客戶端(從主機到 gate):
# ssh -L 5900:localhost:15900 admin@gate
現在 admin 直接連接到 VNC 客戶端:
# vncconnect -display :0 localhost
自 4.3 版開始,OpenSSH 可以使用 tun/tap譯註:tun 爲虛擬點對點設備,tap 爲虛擬以太網設備。 設備來加密一個隧道。其非常類似於基於 TLS 的 VPN 解決方案(像 OpenVPN)。對於 SSH 的一個優勢是,她不需要安裝和配置額外的軟件。另外隧道使用 SSH 認證(像共享密鑰)。其缺點是,對於一個緩慢的連接, 其傳輸效率較低。並且這個隧道依賴於單個(易斷的) TCP 鏈接。這個技術對於快速設置一個基於 IP 的 VPN 來說非常有用。她對於用單個
TCP 端口轉發沒有限制,並且在所有 3/4 層 協議像 ICMP、TCP/UDP 等上都可用。不管怎麼樣,下面這些選擇在 sshd_conf 文件中是必須的:
PermitRootLogin yes
PermitTunnel yes
單個 P2P 連接
這裏,我們用點對點隧道連接 hclient 和 hserver 兩個主機。這個連接是從 hclient 開始到 hserver 的,並且是用 root 來做。這個通道的連接點是 10.0.1.1(服務端)和 10.0.1.2(客戶端),然後我們創建設備 tun5(當然也可以是其它數字)。這個過程非常簡單:
- 使用 SSH 的通道選項 -w 來連接
- 設置隧道的 IP 地址。服務端和客戶端各一次。
連接到服務端
連接始於客戶端,然後再服務端執行命令。
Linux上的服務端
cli># ssh -w5:5 root@hserversrv># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # 在服務端 shell 上執行
FreeBSD上的服務端
cli># ssh -w5:5 root@hserversrv># ifconfig tun5 10.0.1.1 10.0.1.2 # 在服務端 shell 上執行
連接到客戶端
在客戶端上執行命令:
cli># ifconfig tun5 10.0.1.2 netmask 255.255.255.252 # Linux上的客戶端cli># ifconfig tun5 10.0.1.2 10.0.1.1 # FreeBSD上的客戶端
現在兩個主機都連上了,並且可以在任何 3/4 層協議上使用此通道 IP 地址透明的通訊。
連接兩個網絡
除 上面的 p2p 設置外,一個更有用的是SSH VPN 用兩個 gate 連接兩個私有網絡。假設有這樣一個例子,netA 爲 192.168.51.0/24 還有 netB 爲 192.168.16.0/24。設置過程同上面相似,我們只需要添加 routing。如果 gate 不同於默認網關,那在私有網絡接口上必須開啓 NAT。
192.168.51.0/24 (netA)|gateA <-> gateB|192.168.16.0/24 (netB)
- 使用隧道選項 -w 連接 SSH。
- 配置隧道的 IP 地址。服務端和客戶端各一次。
- 爲兩個網絡添加 routing。
- 如果需要,在 gate 的私有網絡接口上開啓 NAT。
設置是從 netA 中的 gasteA 開始的.
連接 gateA 到 gateB
連接從 gateA 開始,命令執行於 gateB。
Linux 上的 gateB
gateA># ssh -w5:5 root@gateB
gateB># ifconfig tun5 10.0.1.1 netmask 255.255.255.252 # 在 gateB 的 shell 中執行
gateB>#
route add -net 192.168.51.0 netmask 255.255.255.0 dev tun5
gateB># echo 1 > /proc/sys/net/ipv4/ip_forward
# 如果不是默認網關gateB># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
FreeBSD 上的 gateB
gateA># ssh -w5:5 root@gateB
# 創建 tun5 設備gateB># ifconfig tun5 10.0.1.1 10.0.1.2
# 在 gateB 的 shell 中執行gateB># route add
192.168.51.0/24 10.0.1.2
gateB># sysctl net.inet.ip.forwarding=1 # 如果不是默認網關
gateB># natd -s -m -u -dynamic -n fxp0 # 看
NATgateA>#
sysctl net.inet.ip.fw.enable=1
配置 gateA
在 gateA 上執行命令:
Linux 上的 gateA
gateA># ifconfig tun5 10.0.1.2 netmask 255.255.255.252
gateA>#
route add -net 192.168.16.0 netmask 255.255.255.0 dev tun5
gateA># echo 1 > /proc/sys/net/ipv4/ip_forward
gateA># iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE
FreeBSD 上的 gateA
gateA># ifconfig tun5 10.0.1.2 10.0.1.1
gateA>#
route add 192.168.16.0/24 10.0.1.2
gateA># sysctl net.inet.ip.forwarding=1
gateA># natd -s -m -u -dynamic -n fxp0 # 看
NATgateA>#
sysctl net.inet.ip.fw.enable=1
現在兩個私有網絡都可以通過 SSH VPN 來透明的連接。如果 gate 不是默認網關,那麼 IP 轉發和 NAT 設置都是必須的。在這種情況下,客戶端將不知道在哪裏轉發響應(response),並且 NAT 必須是開啓的。
Sudo 可以給用戶一些超級用戶的權限而不需要 root 密碼。Sudo 對於一個服務器和工作站混合的多用戶環境來說非常有用。使用 sudo 運行命令:
# sudo /etc/init.d/dhcpd restart # 用 root 權限運行 rc 腳本
# sudo -u sysadmin whoami
# 使用其他用戶運行命令
配置
Sudo 的配置在 /etc/sudoers
中,並且只能用 visudo
編輯譯註:並不是說不能用其他編輯器編輯,而是因爲 visudo
會對其語法進行嚴格檢查,避免給系統帶來嚴重後果。。其基本語法是(列表是以逗號分隔的):
user hosts = (runas) commands # 在 /etc/sudoers 中
users
一個或多個用戶或是%用戶組(像 %wheel) 來獲得權限hosts
主機列表(或 ALL)runas
列出用戶以何種身份(或 ALL)來執行命令,放在 ( ) 內!commands
列出可被 users 以 runas 或 root 權限運行的命令(或 ALL)
另外一些關鍵字可以定義別名,他們是 User_Alias, Host_Alias, Runas_Alias 和 Cmnd_Alias。這對於一些較大的設置比較有用。下面是 sudoers 例子:
# cat /etc/sudoers
# 主機別名
Host_Alias DMZ = 212.118.81.40/28
Host_Alias DESKTOP = work1, work2
# 用戶別名 和 runas 別名
User_Alias ADMINS = colin, luca, admin
User_Alias DEVEL = joe, jack, julia
Runas_Alias DBA = oracle,pgsql
# 命令別名,其值爲全路徑命令
Cmnd_Alias SYSTEM = /sbin/reboot,/usr/bin/kill,/sbin/halt,/sbin/shutdown,/etc/init.d/
Cmnd_Alias PW = /usr/bin/passwd [A-z]*, !/usr/bin/passwd root
# Not root pwd!Cmnd_Alias DEBUG = /usr/sbin/tcpdump,/usr/bin/wireshark,/usr/bin/nmap
# 一個真實的規則
root,ADMINS ALL = (ALL) NOPASSWD: ALL
# ADMINS 別名中的用戶可做任何事情不需要密碼
DEVEL DESKTOP = (ALL) NOPASSWD: ALL # 開發人員可在 DESKTOP 別名的主機上做任何事情
DEVEL DMZ = (ALL) NOPASSWD: DEBUG
# 開發人員可以在 DMZ 別名的主機上使用 DEBUG 別名中的命令
# 用戶 sysadmin 可以在 DMZ 服務器上執行一些命令
sysadmin DMZ = (ALL) NOPASSWD: SYSTEM,PW,DEBUG
sysadmin ALL,!DMZ = (ALL) NOPASSWD: ALL
# 可以在非 DMZ 主機上做任何事情
%dba ALL = (DBA) ALL # 用戶組 dba 可以運行 DBA 別名中用戶權限的所有命令
# 所有用戶可以在 DESKTOP 別名的主機上 掛載/卸載 CD-ROMALL DESKTOP = NOPASSWD: /sbin/mount /cdrom,/sbin/umount /cdrom
Linux with LUKS | Linux
dm-crypt only | FreeBSD GELI | FreeBSD
只使用密碼
有(許多)其他替代方法來加密磁盤,我只呈現我所知道和使用的方法。請記住,安全只是系統還未經過實際考驗而已。入侵者可以輕易通過鍵盤事件記錄密碼。此外,當已經加載了分區,其數據是可以自由訪問的,並不會阻止入侵者去訪問它。
Linux
這部分我們使用可用於 2.6 內核的 Linux dm-crypt (device-mapper)。在這個實例中,讓我們加密 /dev/sdc1
分區,它可爲任何其他分區、磁盤、USB或者用 losetup
創建的基於文件的分區。對於基於文件的分區,我們使用 /dev/loop0
。看 鏡像文件分區。Device
mapper 利用標籤來標識一個分區。我們使用 sdc1
作爲此標籤,但可以爲任何字符串。
dm-crypt with LUKS
LUKS 和 dm-crypt 是較好的加密技術,並且可爲同一個分區設置多個口令,更改密碼也很方便。可簡單輸入 # cryptsetup --help
來測試 LUKS 是否可用。如果沒有顯示任何關於 LUKS 的信息,可看下面Without
LUKS 的介紹。第一步如果需要的話創建一個分區:fdisk /dev/sdc
。
創建加密分區
# dd if=/dev/urandom of=/dev/sdc1 # 可選
# cryptsetup -y luksFormat /dev/sdc1
# 這破壞了在 sdc1 上的數據
# cryptsetup luksOpen /dev/sdc1 sdc1
# mkfs.ext3 /dev/mapper/sdc1 # 創建 ext3 文件系統
# mount -t ext3 /dev/mapper/sdc1 /mnt
# umount /mnt
# cryptsetup luksClose sdc1
# Detach 已加密的分區
Attach
# cryptsetup luksOpen /dev/sdc1 sdc1
# mount -t ext3 /dev/mapper/sdc1 /mnt
Detach
# umount /mnt
# cryptsetup luksClose sdc1
dm-crypt without LUKS
# cryptsetup -y create sdc1 /dev/sdc1 # 或任何其他分區像 /dev/loop0
# dmsetup ls
# 檢查一下,將顯示:sdc1 (254, 0)
# mkfs.ext3 /dev/mapper/sdc1 # 只有第一次要這麼做!
# mount -t ext3 /dev/mapper/sdc1 /mnt
# umount /mnt/
# cryptsetup remove sdc1
# Detach 已加密的分區
這樣做等同於(非 mkfs 部分) re-attach 分區。如果密碼不正確,mount 命令將會失敗。對於這個例子,只要簡單的移除 sdc1 (cryptsetup remove sdc1
)並重建即可。
FreeBSD
兩個流行的 FreeBSD 磁盤加密模塊爲 gbde
和 geli
。我現在使用 geli
原因是它夠快並且它使用加解密硬件加速設備。詳情可看 FreeBSD
使用手冊 18.6http://www.freebsd.org/handbook/disks-encrypting.html。geli
模塊必須已編譯或加載進內核:
options GEOM_ELI
device crypto # 內核配置文件中加入這兩行
# echo 'geom_eli_load="YES"' >> /boot/loader.conf
# 也可以在系統引導時加載或者做:kldload geom_eli
使用密碼和密鑰
我爲一個典型的磁盤加密使用這些設置,其使用了一個口令和一個加密主密鑰(master key)的密鑰。這意味着你需要密碼和生產的密鑰 /root/ad1.key
來 attach 分區。主密鑰存儲在這個加密分區中並且不可見。看下面爲 USB 或 映像文件的加密設置。
創建加密分區
# dd if=/dev/random of=/root/ad1.key bs=64 count=1 # 加密主密鑰的密鑰
# geli init -s 4096 -K /root/ad1.key /dev/ad1
# 對於磁盤也可用 -s 8192
# geli attach -k /root/ad1.key /dev/ad1 # 將 /dev/ad1 與所生成的密鑰 /root/ad1.key 關聯
# dd if=/dev/random of=/dev/ad1.eli bs=1m
# 可選,需要很長時間
# newfs /dev/ad1.eli # 創建文件系統
# mount /dev/ad1.eli /mnt
Attach
# geli attach -k /root/ad1.key /dev/ad1
# fsck -ny -t ffs /dev/ad1.eli # 檢查文件系統
# mount /dev/ad1.eli /mnt
Detach
Detach 步驟會在關機時自動完成。
# umount /mnt
# geli detach /dev/ad1.eli
/etc/fstab
加密分區在 /etc/fstab 中配置成自動加載。系統啓動時會詢問加密分區的密碼。對於本例下列設置是必須的:
# grep geli /etc/rc.conf
geli_devices="ad1"
geli_ad1_flags="-k /root/ad1.key"
# grep geli /etc/fstab
/dev/ad1.eli /home/private ufs rw 0 0
僅用密碼
加密一個 USB stick 或者映像文件使用密碼而不是密鑰來得更方便。這種情況下,沒有必要隨身攜帶額外的密鑰文件。所做步驟同上面非常相似,只是不需要密鑰文件。讓我們來加密一個 1 GB 的映像文件/cryptedfile
。
# dd if=/dev/zero of=/cryptedfile bs=1M count=1000 # 1 GB 文件
# mdconfig -at vnode -f /cryptedfile
# geli init /dev/md0
# 僅用密碼加密
# geli attach /dev/md0
# newfs -U -m 0 /dev/md0.eli
# mount /dev/md0.eli /mnt
# umount /dev/md0.eli
# geli detach md0.eli
現在可以把這個映像文件加載成僅需密碼的文件系統。
# mdconfig -at vnode -f /cryptedfile
# geli attach /dev/md0
# mount /dev/md0.eli /mnt
服務器設置 | CVS
測試 | SSH 隧道 | CVS
使用
服務器設置
CVS 環境初始化
決定主 repository 將要創建和重置的 cvs 根目錄。比如 /usr/local/cvs (根):
# mkdir -p /usr/local/cvs
# setenv CVSROOT /usr/local/cvs # 設置 CVSROOT 環境變量(本地)
# cvs init
# 創建所有初始化 CVS 配置文件
# cd /root
# cvs checkout CVSROOT # 簽出配置文件來修改他們
# cd CVSROOT
edit config ( fine as it is)
# cvs commit config
cat >> writers
# 創建 writers 文件 (也可爲 readers)
colin
^D # 使用 [Control][D] 退出編輯
# cvs add writers
# 添加文件 writers 進 repository
# cvs edit checkoutlist
# cat >> checkoutlist
writers
^D # 使用 [Control][D] 退出編輯
# cvs commit
# 提交所有配置更改
添加一個 readers 文件,如果你要區分讀寫權限的話。注意: 不要在主 cvs 中直接編輯文件,而應該簽出要編輯的文件,修改完成後再簽入。我們所做的文件 writers 用來定義可寫權限。
下面有三種流行的方式去訪問 CVS。前兩個不需要任何進一步的配置。看 CVSROOT 部分的實例瞭解如何使用它們:
- 直接本的訪問文件系統。用戶需要有足夠的權限來直接訪問 CVS,除了要登錄到操作系統,沒有進一步的驗證。然而這僅對本地 repository 纔有用。
- 使用 ext 協議通過 ssh 來遠程訪問。任何有 ssh shell 賬戶和在 CVS 服務器上可讀寫權限的都可直接使用 ext 協議通過 ssh 來訪問 CVS,而不需要任何額外的隧道。沒有服務器來處理運行在 CVS 上的驗證工作。ssh 登錄會去驗證。
- 用 pserver 來遠程訪問。這是對於有較大用戶量的首選方法,用戶由 CVS 的 pserver 通過一個專門的密碼數據庫來驗證,因此不需要本地用戶帳戶。這種設置在下面會有說明。
用 inetd 設置網絡
如果不需要網絡訪問,CVS 可以運行於本地。對於遠程訪問,在 /etc/inetd.conf (Suse 爲 /etc/xinetd.d/cvs)中配置如下行,可讓守護進程 inetd 啓動 pserver:
cvspserver stream tcp nowait cvs /usr/bin/cvs cvs --allow-root=/usr/local/cvs pserver
這是個用來阻斷從 internet 訪問 cvs 端口的好方法,可使用 ssh 隧道來遠程的訪問 repository。
單獨認證
CVS 用戶可能不是操作系統的一部分(即不是本地用戶)。這其實可從安全的角度去看。簡單的添加一個叫 passwd (in the CVSROOT directory) 的文件,其包含 crypt 格式的用戶登錄名和密碼。這也可以使用 apache 的 htpasswd 工具來完成。
注意:這個 passwd 文件僅僅是文件,可以在 CVSROOT 中直接編輯。它不能被簽出。更多信息請用 htpasswd --help
# htpasswd -cb passwd user1 password1 # -c 創建文件
# htpasswd -b passwd user2 password2
現在添加 :cvs
到每行的結尾處,用來告訴 cvs 服務器更改用戶到 cvs (或任何你正在運行的 cvs 服務器下)。它看起來像這樣:
# cat passwd
user1:xsFjhU22u8Fuo:cvs
user2:vnefJOsnnvToM:cvs
測試它
測試作爲一般用戶登錄(比如我)
CVSROOT 變量
這是個環境變量用來指定 repository 的位置。對於本地使用,該變量只需設置成 repository 的目錄。對於通過網絡使用,傳輸協議必須指定。使用 setenv CVSROOT string
(csh, tcsh shell) 或者 export
CVSROOT=string
( sh, bash shell) 設置 CVSROOT 環境變量。
# setenv CVSROOT :pserver:<username>@<host>:/cvsdirectory
For example:
# setenv CVSROOT /usr/local/cvs # 僅限本的使用
# setenv CVSROOT :local:/usr/local/cvs
# 同上
# setenv CVSROOT :ext:user@cvsserver:/usr/local/cvs # 通過 SSH 直接訪問
# setenv CVS_RSH ssh
# ext 協議訪問# setenv CVSROOT :pserver:
[email protected]:/usr/local/cvs # 通過 pserver 網絡訪問
一旦登錄成功就可導入一個新項目進 repository:cd 進入你的項目根目錄
cvs import <module name> <vendor tag> <initial tag>
在 repository 中有個名叫 MyProject 新項目(之後用來簽出)。CVS 會導入當前目錄的內容進新項目。
簽出:
# cvs -d :pserver:
[email protected]:/usr/local/cvs checkout MyProject
或者
# cvs checkout MyProject
通過 SSH 隧道訪問 CVS
我們需要兩個 shell 來做這個。在第一個 shell 中,我們連接到 cvs 服務器並對 cvs 連接進行端口轉發(port-forward)。在第二個 shell 中,我們就像在本地一樣使用 cvs。
在 shell 1:
# ssh -L2401:localhost:2401 colin@cvs_server # 直接連接到 cvs 服務器。或:
# ssh -L2401:cvs_server:2401 colin@gateway
# 使用一個網關間接連接到 cvs 服務器
在 shell 2:
# setenv CVSROOT :pserver:colin@localhost:/usr/local/cvs
# cvs login
Logging in to :pserver:colin@localhost:2401/usr/local/cvs
CVS password:
# cvs checkout MyProject/src
CVS 命令及其使用
導入
該 import 命令用來添加整個目錄,它必須運行於要導入的目錄中。比如,目錄 /devel/ 包含的所有文件和子目錄要導入。該目錄名在 CVS 中(模塊)將會稱爲 "myapp"。
# cvs import [options] directory-name vendor-tag release-tag
# cd /devel # 必須在該目錄中來導入
# cvs import myapp Company R1_0
# 修訂(release)標籤可以爲任何單個單詞
在添加了一個新目錄 "/devel/tools/" 後,也可這麼導入。
# cd /devel/tools
# cvs import myapp/tools Company R1_0
簽出、更新和提交
# cvs co myapp/tools # 僅會簽出 tools 目錄
# cvs co -r R1_1 myapp
# 簽出修訂版本爲 R1_1 的 myapp (sticky)
# cvs -q -d update -P # 典型的 CVS 更新
# cvs update -A
# 重置所有 sticky 標籤(或日期、選項)
# cvs add newfile # 添加一個新文件
# cvs add -kb newfile
# 添加一個二進制文件
# cvs commit file1 file2 # 僅提交這兩個文件
# cvs commit -m "message"
# 提交所有更改併爲這個更改添加日誌消息
創建一個 patch
It is best to create and apply a patch from the working development directory related to the project, or from within the source directory.
# cd /devel/project
# diff -Naur olddir newdir > patchfile # Create a patch from a directory or a file
# diff -Naur oldfile newfile > patchfile
應用一個 patch
Sometimes it is necessary to strip a directory level from the patch, depending how it was created. In case of difficulties, simply look at the first lines of the patch and try -p0, -p1 or -p2.
# cd /devel/project
# patch --dry-run -p0 < patchfile # Test the path without applying it
# patch -p0 < patchfile
# patch -p1 < patchfile
# strip off the 1st level from the path
Server setup | SVN+SSH | SVN
over http | SVN usage
Subversion (SVN)http://subversion.tigris.org/ is a version control system designed to be the
successor of CVS (Concurrent Versions System). The concept is similar to CVS, but many shortcomings where improved. See also the SVN
bookhttp://svnbook.red-bean.com/en/1.4/.
Server setup
The initiation of the repository is fairly simple (here for example /home/svn/
must exist):
# svnadmin create --fs-type fsfs /home/svn/project1
Now the access to the repository is made possible with:
file://
Direct file system access with the svn client with. This requires local permissions on the file system.svn://
or svn+ssh://
Remote
access with the svnserve server (also over SSH). This requires local permissions on the file system.http://
Remote access with webdav using apache. No local users are necessary for this method.
Using the local file system, it is now possible to import and then check out an existing project. Unlike with CVS it is not necessary to cd into the project directory, simply give the full path:
# svn import /project1/ file:///home/svn/project1/trunk -m 'Initial import'
# svn checkout file:///home/svn/project1
The new directory "trunk" is only a convention, this is not required.
Remote access with ssh
No special setup is required to access the repository via ssh, simply replace file://
with svn+ssh/hostname
.
For example:
# svn checkout svn+ssh://hostname/home/svn/project1
As with the local file access, every user needs an ssh access to the server (with a local account) and also read/write access. This method might be suitable for a small group. All users could belong to a subversion group which owns
the repository, for example:
# groupadd subversion
# groupmod -A user1 subversion
# chown -R root:subversion /home/svn
# chmod -R 770 /home/svn
Remote access with http (apache)
Remote access over http (https) is the only good solution for a larger user group. This method uses the apache authentication, not the local accounts. This is a typical but small apache configuration:
LoadModule dav_module modules/mod_dav.so
LoadModule dav_svn_module modules/mod_dav_svn.so
LoadModule authz_svn_module modules/mod_authz_svn.so # Only for access control
<Location /svn>
DAV svn
# any "/svn/foo" URL will map to a repository /home/svn/foo
SVNParentPath /home/svn
AuthType Basic
AuthName "Subversion repository"
AuthzSVNAccessFile /etc/apache2/svn.acl
AuthUserFile /etc/apache2/svn-passwd
Require valid-user
</Location>
The apache server needs full access to the repository:
# chown -R www:www /home/svn
Create a user with htpasswd2:
# htpasswd -c /etc/svn-passwd user1 # -c creates the file
Access control svn.acl example
# Default it read access. "* =" would be default no access
[/]
* = r
[groups]
project1-developers = joe, jack, jane
# Give write access to the developers
[project1:]
@project1-developers = rw
SVN commands and usage
See also the Subversion Quick Reference Cardhttp://www.cs.put.poznan.pl/csobaniec/Papers/svn-refcard.pdf. Tortoise
SVNhttp://tortoisesvn.tigris.org is a nice Windows interface.
Import
A new project, that is a directory with some files, is imported into the repository with the import
command. Import is also used
to add a directory with its content to an existing project.
# svn help import # Get help for any command # Add a new directory (with content) into the src dir on project1# svn import /project1/newdir http://host.url/svn/project1/trunk/src -m 'add
newdir'
Typical SVN commands
# svn co http://host.url/svn/project1/trunk # Checkout the most recent version
# Tags and branches are created by copying
# svn mkdir http://host.url/svn/project1/tags/ # Create the tags directory
# svn copy -m "Tag rc1 rel." http://host.url/svn/project1/trunk http://host.url/svn/project1/tags/1.0rc1
# svn status [--verbose]
# Check files status into working dir
# svn add src/file.h src/file.cpp # Add two files
# svn commit -m 'Added new class file'
# Commit the changes with a message
# svn ls http://host.url/svn/project1/tags/ # List all tags
# svn move foo.c bar.c
# Move (rename) files# svn delete some_old_file # Delete files
less | vi | mail | tar | dd | screen | find | 混雜的
less
less
命令用來在控制檯中分屏顯示文本文檔。它在許多發行版中可用。
# less unixtoolbox.xhtml
一些重要指令(^N 代表 [control]-[N]):
- h H 顯示指令的彙總列表
- f ^F ^V SPACE 向前滾動一屏(或者 N 行)
- b ^B ESC-v 向後滾動一屏(或者 N 行)
- F 向前滾動;類似於"tail -f"
- /pattern 向前搜索匹配該模式的行
- ?pattern 向後搜索匹配該模式的行
- n 重複之前的搜索
- N 反方向重複之前的搜索
- q 退出
vi
Vi 在任何 Linux/Unix 發行安裝版(gentoo 沒有?)上都存在。因此,我們有必要了解一些基本的命令。Vi 有兩個模式:命令模式和插入模式。使用 [ESC] 鍵可進入命令模式,使用 i 鍵可進入插入模式。如果你迷失了,可在命令模式下鍵入 :
help
。
編輯器 nano
和 pico
通常也都可用,而且更容易(IMHO)使用。
Quit
- :w newfilename 保存文件爲 newfilename
- :wq or :x 保存並退出
- :q! 退出但不保存
移動和查找
- /string 向前查找 string
- ?string 向後查找 string
- n 同方向重複上一次搜索命令
- N 反方向重複上一次搜索命令
- { 光標移至段落結尾
- } 光標移至段落開頭
- 1G 光標移至文件的第一行首
- nG 光標移至文件的第 n 行首
- G 光標移至文件的最後一行首
- :%s/OLD/NEW/g 替換所有查找到的 OLD 爲 NEW
刪除文本
- dd 刪除當前行
- D 刪除光標到當前行末尾的字符
- dw 刪除單詞
- x 刪除字符
- u 回覆上一次操作
- U 回覆所有此行的更改
mail
mail
命令是一個讀取和發送郵件的應用程序,她通常已安裝。要發送一封郵件,可以簡單的輸入 "mail user@domain"。其第一行爲主題,然後是郵件內容。在一個新行中使用單個點(.)來結束併發送郵件。例子:
Subject: Your text is full of typos
"For a moment, nothing happened. Then, after a second or so,
nothing continued to happen."
.
EOT
#
這同樣可用於管道:
也是測試郵件服務器的簡單方法。
tar
命令 tar
(磁帶存檔) 可以爲文件和目錄創建檔案。歸檔文件 .tar 是未壓縮的,一個壓縮過的歸檔文件的後綴是 .tgz 或 .tar.gz (zip) 或者 .tbz (bzip2)。不要使用絕對路徑建立一個歸檔文件,你可能要解開這個歸檔文件到某個地方。一些常用命令如下:
創建
# cd /
# tar -cf home.tar home/ # 歸檔整個 /home 目錄(c 爲創建)
# tar -czf home.tgz home/
# 等同於 zip 壓縮# tar -cjf home.tbz home/ # 等同於 bzip2 壓縮
從一個目錄樹中只包含一個(或2個)目錄,並保持相對目錄結構。舉個例子,/usr/local/etc 和 /usr/local/www,它們在歸檔文件中的第一層目錄是 local/。
# tar -C /usr -czf local.tgz local/etc local/www
# tar -C /usr -xzf local.tgz # 釋放 local 目錄到 /usr
# cd /usr; tar -xzf local.tgz
# 同上面一樣
釋放(Extract)
# tar -tzf home.tgz # 列出歸檔文件中的所有文件,並不釋放
# tar -xf home.tar
# 釋放歸檔文件(x 爲釋放)
# tar -xzf home.tgz # 等同於 zip 壓縮
# tar -xjf home.tgz
# 等同於 bzip2 壓縮# tar -xjf home.tgz home/colin/file.txt # 釋放單個文件
更高級的
# tar c dir/ | gzip | ssh user@remote 'dd of=dir.tgz' # 歸檔壓縮 dir/ 目錄並存儲到遠程主機上
# tar cvf - `find . -print` > backup.tar
# 歸檔當前目錄
# tar -cf - -C /etc . | tar xpf - -C /backup/etc # 拷貝目錄
# tar -cf - -C /etc . | ssh user@remote tar xpf - -C /backup/etc
# 遠程拷貝# tar -czf home.tgz --exclude '*.o' --exclude 'tmp/' home/
dd
程序 dd
(磁盤備份(disk dump) 或 destroy disk,也可看 dd
的含義) 用來拷貝分區、磁盤或者其它拷貝。通常這麼用:
# dd if=<source> of=<target> bs=<byte size> conv=<conversion>
重要的 conv 選項:
notrunc
不截短輸出文件noerror
出錯時不停止處理(e.g. 壞扇區)sync
把每個輸入塊填充到ibs個字節,不足部分用空(NUL)字符補齊
默認字節大小爲 512 (一個扇區)。MBR 處於磁盤的第一個扇區,之後的 63 個扇區是空的。較大的字節大小可以加快拷貝速度但也需要更多的內存。
備份和恢復
# dd if=/dev/hda of=/dev/hdc bs=16065b # 拷貝磁盤到磁盤(相同大小)
# dd if=/dev/sda7 of /home/root.img bs=4096 conv=notrunc,noerror
# 備份 /
# dd if /home/root.img of=/dev/sda7 bs=4096 conv=notrunc,noerror # 恢復 /
# dd bs=1M if=/dev/ad4s3e | gzip -c > ad4s3e.gz
# 壓縮備份
# gunzip -dc ad4s3e.gz | dd of=/dev/ad0s3e bs=1M # 解壓恢復
# dd bs=1M if=/dev/ad4s3e | gzip | ssh eedcoba@fry 'dd of=ad4s3e.gz'
# 也可爲遠程的
# gunzip -dc ad4s3e.gz | ssh eedcoba@host 'dd of=/dev/ad0s3e bs=1M'
# dd if=/dev/ad0 of=/dev/ad2 skip=1 seek=1 bs=4k conv=noerror # 忽略 MBR
# 如果目標(ad2)比較小,這是必須的。
恢復
該 dd
命令會讀取分區的每一個區塊,即所有區塊。對於有問題的區塊,最好使用 conv=sync,noerror
選項,dd
將會跳過壞的區塊併入 0。因此,這就是設置塊大小等於或小於磁盤塊大小的重要性。1k 大小似乎安全,用 bs=1k
來設置它。假如一個磁盤有壞扇區並且有個分區的數據要恢復,那麼用 dd 工具創建一個鏡像文件,掛載這個鏡像文件,然後拷貝內容到新的磁盤中。如果用了 noerror
選項,dd
會跳過壞扇區並寫入 0,也即壞扇區中的內容會丟失。
# dd if=/dev/hda of=/dev/null bs=1m # 檢查壞扇區
# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc | gzip | ssh \
# 發送到遠程
root@fry 'dd of=hda1.gz bs=1k'
# dd bs=1k if=/dev/hda1 conv=sync,noerror,notrunc of=hda1.img # 存儲爲一個映像文件
# mount -o loop /hda1.img /mnt
# 掛載這個映像文件
# rsync -ax /mnt/ /newdisk/ # 拷貝到一個新磁盤
# dd if=/dev/hda of=/dev/hda
# 刷新磁狀態 # 上面的命令對於刷新磁盤(refresh disk)很有用。這絕對安全,但必須先卸載磁盤。
刪除
# dd if=/dev/zero of=/dev/hdc # 刪除全部數據
# dd if=/dev/urandom of=/dev/hdc
# 更好的刪除全部數據譯註:/dev/urandom 設備文件提供了一種比單獨使用$RANDOM更好的,能產生更"隨機"的隨機數的方法。# kill -USR1 PID # 查看 dd 進度(僅Linux!)
MBR 技巧
MBR 包含了引導程序和分區表,它的大小爲 512 字節。前 446 字節爲引導程序,446 到 512 字節爲分區表。
# dd if=/dev/sda of=/mbr_sda.bak bs=512 count=1 # 完全備份 MBR
# dd if=/dev/zero of=/dev/sda bs=512 count=1
# 刪除 MBR 和分區表
# dd if=/mbr_sda.bak of=/dev/sda bs=512 count=1 # 完全恢復MBR
# dd if=/mbr_sda.bak of=/dev/sda bs=446 count=1
# 僅回覆引導程序# dd if=/mbr_sda.bak of=/dev/sda bs=1 count=64 skip=446 seek=446 # 恢復分區表
screen
Screen 提供了兩個主要功能:
- 在一個終端內運行多個終端會話(terminal session)。
- 一個已啓動的程序與運行它的真實終端分離的,因此可運行於後臺。真實的終端可以被關閉,還可以在稍後再重新接上(reattached)。
簡短實例
開啓 screen:
# screen
在 screen 會話中,我們可以開啓一個長時間運行的程序(如 top)。Detach 這個終端,之後可以從其他機器 reattach 這個相同的終端(比如通過 ssh)。
# top
現在用 Ctrl-a Ctrl-d 來 detach。Reattach 終端:
# screen -r
或更好的:
# screen -R -D
現在 attach 到這裏。具體意思是:先試圖恢復離線的 screen 會話。若找不到離線的 screen 會話,即建立新的 screen 會話給用戶。
Screen 命令 (在 screen 中)
所有命令都以 Ctrl-a 開始。
- Ctrl-a ? 各功能的幫助摘要
- Ctrl-a c 創建一個新的 window (終端)
- Ctrl-a Ctrl-n 和 Ctrl-a Ctrl-p 切換到下一個或前一個 window
- Ctrl-a Ctrl-N N 爲 0 到 9 的數字,用來切換到相對應的 window
- Ctrl-a " 獲取所有正在運行的 window 的可導航的列表
- Ctrl-a a 清楚錯誤的 Ctrl-a
- Ctrl-a Ctrl-d 斷開所有會話,會話中所有任務運行於後臺
- Ctrl-a x 用密碼鎖柱 screen 終端
當程序內部運行終端關閉並且你登出該終端時,該 screen 會話就會被終止。
Find
一些重要選項:
-x
(BSD) -xdev
(Linux)
留於同一文件系統 (fstab 中的 dev)-exec cmd {} \;
執行命令並用全路徑替換 {}-iname
同 -name 一樣,但不區分大小寫-ls
顯示關於文件的信息(同 ls -la)-size n
n 爲 +-n (k M G T P)-cmin n
查找系統中最後 n 分鐘改變文件狀態的文件
# find . -type f ! -perm -444 # 尋找所有無法讀取的文件
# find . -type d ! -perm -111
# 尋找所有無法訪問的目錄
# find /home/user/ -cmin 10 -print # 尋找最後 10 分鐘創建或修改的文件
# find . -name '*.[ch]' | xargs grep -E 'expr'
# 在當前目錄及子目錄搜索 'expr' 表達式
# find / -name "*.core" | xargs rm # 尋找 core 垃圾並刪除它們(也可試試 core.*)
# find / -name "*.core" -print -exec rm {} \;
# 另一種語法
# 尋找圖像文件並創建一個歸檔文件,iname 爲不區分大小寫。-r 爲附加
# find . −iname"∗.png"−o−iname"∗.jpg"
-print -exec tar -rf images.tar {} \;
# find . -type f -name "*.txt" ! -name README.txt -print
# 除 README.txt 的文件
# find /var/ -size +10M -exec ls -lh {} \; # 查找 > 10 MB 的文件
# find /var/ -size +10M -ls
# 這個更簡單
# find . -size +10M -size -50M -print
# find /usr/ports/ -name work -type d -print -exec rm -rf {} \; # 清理 port
# 以 SUID 查找文件;這些文件很脆弱,必須保持安全。# find / -type f -user root -perm -4000 -exec ls -l {} \;
小心 xarg 或 exec,因爲當文件或目錄中包含空格時可能會返回錯誤的結果。在有疑惑時用 "-print0 | xargs -0" 代替 "| xargs"。選項 -print0 必須在 find 命令的最後。看這個不錯的 find
迷你教程http://www.hccfl.edu/pollock/Unix/FindCmd.htm.
# find . -type f | xargs ls -l # 不能工作於有空格的名字
# find . -type f -print0 | xargs -0 ls -l
# 可工作於有空格的名字# find . -type f -exec ls -l '{}' \; # 或使用用於 -exec 的引用 '{}'
混雜的
# which command # 顯示命令的全路徑名
# time command
# 顯示一個命令執行完成所用的時間
# time cat # 使用 time 作爲秒錶,用 Ctrl-c 來停止
# set | grep $USER
# 列顯當前環境變量
# cal -3 # 顯示三個月日曆
# date [-u|--utc|--universal] [MMDDhhmm[[CC]YY][.ss]]
# date 10022155
# 設置日期和時間
# whatis grep # 顯示命令的簡短信息
# whereis java
# 查詢命令的的路徑和標準目錄
# setenv varname value # 設置環境變量,設置變量 varname 的值爲 value (csh/tcsh)
# export varname="value"
# 設置環境變量,設置變量 varname 的值爲 value (sh/ksh/bash)
# pwd # 顯示當前工作目錄
# mkdir -p /path/to/dir
# 如果存在不顯示錯誤,建立所需的上級目錄
# mkdir -p project/{bin,src,obj,doc/{html,man,pdf},debug/some/more/dirs}
# rmdir /path/to/dir # 移除目錄
# rm -rf /path/to/dir
# 移除目錄和其內容(強制)
# cp -la /dir1 /dir2 # 存檔、硬連接目錄所有文件,用來替代拷貝
# cp -lpR /dir1 /dir2
# 同上 (FreeBSD)
# cp unixtoolbox.xhtml{,.bak} # 拷貝文件成新擴展名的快速方法
# mv /dir1 /dir2
# 修改目錄名
PostgreSQL
更改 root 用戶或其它用戶的密碼
# psql -d template1 -U pgsql
> alter user pgsql with password 'pgsql_password'; # pgsql 爲需要更改密碼的用戶名
創建用戶和數據庫
命令 createuser
, dropuser
, createdb
和 dropdb
等同於
SQL 命令譯註:其實是一個 Shell 腳本的快捷方式。我們創建一個新用戶叫 bob 和一個數據庫叫 bobdb;使用數據庫的超級用戶 pgsql 來創建:
# createuser -U pgsql -P bob # -P 會請求一個祕密
# createdb -U pgsql -O bob bobdb
# 新數據庫 bobdn 的所有者是 bob譯註:通常,執行這個命令的數據庫用戶成爲新數據庫的所有者。不過,如果執行用戶擁有合適的權限,那麼他可以通過 -O 指定合適的用戶。
# dropdb bobdb # 刪除數據庫 bobdb
# dropuser bob
# 刪除用戶 bob
一般數據庫認證機制配置在 pg_hba.conf 文件中。
允許遠程訪問
文件 $PGSQL_DATA_D/postgresql.conf
可指定綁定地址。對於 Postgres 8.x 通常爲 listen_addresses
= '*'
。
文件 $PGSQL_DATA_D/pg_hba.conf
定義了訪問控制。舉例:
# TYPE DATABASE USER IP-ADDRESS IP-MASK METHOD
host bobdb bob 212.117.81.42 255.255.255.255 password
host all all 0.0.0.0/0 password
備份和恢復
使用 pgsql 或 postgres 用戶來完成備份與恢復。下面是備份和恢復單個數據庫:
# pg_dump --clean dbname > dbname_sql.dump
# psql dbname < dbname_sql.dump
備份和恢復所有數據庫(包括用戶):
# pg_dumpall --clean > full.dump
# psql -f full.dump postgres
在這個例子中,你可以聲明任意現有的數據庫進行連接,但是如果你是向一個空的數據庫集羣裝載,那麼 postgres 應該是比較好的選擇。
MySQL
更改 mysql root 用戶或其它用戶的密碼
方法 1
# /etc/init.d/mysql stop
or
# killall mysqld
# mysqld --skip-grant-tables
# mysqladmin -u root password 'newpasswd'
# /etc/init.d/mysql start
方法 2
# mysql -u root mysql
mysql> UPDATE USER SET PASSWORD=PASSWORD("newpassword") where user='root';
mysql> FLUSH PRIVILEGES; # 使用用戶名替代"root"
mysql> quit
創建用戶和數據庫
# mysql -u root mysql
mysql> CREATE DATABASE bobdb;
mysql>
GRANT ALL ON *.* TO 'bob'@'%' IDENTIFIED BY 'pwd';
# 使用 localhost 替代 % 來限制網絡訪問
mysql> DROP DATABASE bobdb; # 刪除數據庫 bobdb
mysql> DROP USER bob; # 刪除用戶 bob
mysql>
DELETE FROM mysql.user WHERE user='bob and host='hostname';
# 刪除 mysql 數據庫 user 表中 user=bob,host=hostname 的記錄
mysql> FLUSH PRIVILEGES;
允許遠程訪問
遠程訪問通常允許單個數據庫,而不是所有的數據庫。文件 /etc/my.cnf
包含約定的 IP 地址。通常爲 bind-address
=
綁定地址。
# mysql -u root mysql
mysql> GRANT ALL ON bobdb.* TO bob@'xxx.xxx.xxx.xxx' IDENTIFIED BY 'PASSWORD';
mysql>
REVOKE GRANT OPTION ON foo.* FROM bar@'xxx.xxx.xxx.xxx';
mysql> FLUSH PRIVILEGES;
# 使用 'hostname' 也可爲 '%' 來完全訪問
備份和恢復
備份和恢復單個數據庫:
# mysqldump -u root -psecret --add-drop-database dbname > dbname_sql.dump
# mysql -u root -psecret -D dbname < dbname_sql.dump
備份和恢復所有的數據庫:
# mysqldump -u root -psecret --add-drop-database --all-databases > full.dump
# mysql -u root -psecret < full.dump
這裏 mysql root 的密碼爲 "secret",-p 選項後面沒有空格。當單獨使用 -p 選項(不跟密碼),命令行提示符後會要求輸入密碼。
SQLite
SQLitehttp://www.sqlite.org 是一個小而強大的、獨立的(self-contained)、無服務器的(serverless)、零配置的(zero-configuration)
SQL 數據庫。
備份和恢復
實用備份和恢復 SQLite 數據庫命令。舉個例子,你可以編輯備份文件來修改字段的屬性和類型,然後再恢復這個數據庫。這比使用 SQL 命令來得容易。對於 3.x 數據庫可使用 sqlite3
。
# sqlite database.db .dump > dump.sql # 備份
# sqlite database.db < dump.sql
# 恢復
轉換 2.x 到 3.x 數據庫
sqlite database_v2.db .dump | sqlite3 database_v3.db
基礎 | 腳本實例 | sed/實用命令
Bourne shell譯註:Shell 存在很多種,如 bash(Bourne Again Shell),csh(C Shell),tcsh(TC Shell),zsh(Z Shell) 等。通過 ps 命令可識別出正在運行的是哪種 Shell。 (/bin/sh) 存在於所有的 Unix 系統上,並且用她寫的腳本是(完全)可移植的; man
1 sh
是一個好的參考。
基礎
變量和參數
使用 variable=value
的命令格式設置變量,其中 variable 是變量名稱,value是打算賦給該變量的值。使用 $variable 獲取變量值。
MESSAGE="Hello World" # 賦予一個字符串
PI=3.1415
# 賦予一個十進制小數
N=8
TWON=`expr $N * 2` # 算術表達式(只限整數)
TWON=$(($N * 2))
# 另一種語法
TWOPI=`echo "$PI * 2" | bc -l` # 使用 bc 進行浮點運算
ZERO=`echo "c($PI/4)-sqrt(2)/2" | bc -l`
命令行參數:
$0, $1, $2, ... # $0 命令本身
$#
# 命令參數個數$* # 所有參數(也可以是 $@)
一些特殊的變量
$$ # 當前進程 ID
$?
# 最後命令退出狀態碼
command
if [ $
?
!= 0 ]; then
echo "command failed"
fimypath=`pwd`
mypath
=${mypath}/file.txt
echo ${
mypath
##*/} # 只顯示文件名
echo ${
mypath%%.*} # 除了擴展名的全路徑
var2=${var:=string} # 如果var沒有被賦值,則string值先賦值給var, # 然後再賦值給var2
結構控制
for
file
in `ls`
do
echo $
file
done
count
=0
while [ $
count
-lt 5 ]; do
echo $
count
sleep 1
count=$(($
count
+ 1))
done
myfunction() {
find . -type f -name "*.$
1
" -print # $1 爲方法的第一個參數
}
myfunction "txt"
產生一個文件
MYHOME=/home/colin
cat > testhome.sh << _EOF
# 所有_EOF前的代碼都會進入到 testhome.sh 文件中去if [ -d "$
MYHOME
" ] ; then
echo $
MYHOME
exists
else
echo $
MYHOME
does not exist
fi
_EOF
sh testhome.sh
Bourne 腳本實例
來一個小實例,此腳本從本 xhtml 文檔創建一個 PDF 小冊子:
#!/bin/sh
# 此腳本可以創建一份供雙面打印機打印的 PDF 格式的書if [ $
# -ne 1 ];
then
# 檢查參數是否等於 1
echo 1>&2 "Usage: $0 HtmlFile"
exit 1 # 如果不等於1,非0退出
fi
file=$
1 # 文件變量
fname=${file%.*}
# 文件名變量fext=${
file
#*.} # 文件擴展名變量
prince $
file -o $fname.pdf
# www.princexml.compdftops -paper A4 -noshrink $fname.pdf $
fname
.ps # 創建 postscript 小冊子
cat $
fname
.ps |psbook|psnup -Pa4 -2 |pstops -b "2:0,1U(21cm,29.7cm)" > $fname.book.ps
ps2pdf13 -sPAPERSIZE=a4 -sAutoRotatePages=None $
fname
.book.ps $fname.book.pdf
# 在 Windows 上使用 #a4 和 #None!exit 0
# exit 0 意爲成功
一些 sed 命令
這裏是單行 sed 命令的金礦http://student.northpark.edu/pemente/sed/sed1line.txt。還有一個很好的 sed
介紹及教程http://www.grymoire.com/Unix/Sed.html。
sed 's/string1/string2/g' # 替換 string1 爲 string2
sed -i 's/wroong/wrong/g' *.txt
# 用 g 替換所有返回的單詞
sed 's/.∗1/\12/g'
# 修改 anystring1 爲 anystring2
sed '/<p>/,/<\/p>/d' t.xhtml
# 刪除以 <p> 開始,以 </p> 結尾的行
sed '/ *#/d; /^ *$/d' # 刪除註釋和空行
sed 's/[ \t]*$//'
# 刪除行尾空格 (使用 tab 代替 \t)
sed 's/^[ \t]*//;s/[ \t]*$//' # 刪除行頭尾空格
sed 's/[^*]/[&]/'
# 括住首字符 [] top -> [t]opsed = file | sed 'N;s/\n/\t/' > file.num # 爲文件添加行號
正則表達式
一些基本的正則表達式同樣可用於 sed。作爲一個良好的啓蒙,可看 基本正則語法http://www.regular-expressions.info/reference.html。
[\^$.|?*+() # 特殊字符,其他字符將匹配自身
\
# 轉義特殊字符,當成普通字符對待
* # 重複前項 0 次或多次
.
# 單個字符除換行符
.* # 匹配 0 個或多個字符
^
# 匹配字符串行開始處
$ # 匹配字符串行結尾處
.$
# 匹配字符串行最後一個字符
^ $ # 匹配單個空格的行
[^A-Z]
# 匹配任何以 A-Z 字符開始的行
一些實用命令
下列命令對於包含於一個腳本或者單行命令來說很有用。
sort -t. -k1,1n -k2,2n -k3,3n -k4,4n # 排序 IPv4 格式的 IP 地址
echo 'Test' | tr '[:lower:]' '[:upper:]'
# 轉換成大寫
echo foo.bar | cut -d . -f 1 # 返回 foo
PID=$(ps | grep script.sh | grep bin | awk '{print $1}')
# 正在運行名爲 script 腳本的 PID
PID=$(ps axww | grep [p]ing | awk '{print $1}') # ping 的 PID (w/o grep pid)
IP=$(ifconfig $INTERFACE | sed '/.*inet addr:/!d;s///;s/ .*//')
# Linux
IP=$(ifconfig $INTERFACE | sed '/.*inet /!d;s///;s/ .*//') # FreeBSD
if [ `diff file1 file2 | wc -l` != 0 ]; then [...] fi
# 文件改變了?
cat /etc/master.passwd | grep -v root | grep -v \*: | awk -F":" \ # 創建 http passwd
'{ printf("%s:%s\n", $1, $2) }' > /usr/local/etc/apache2/passwd
testuser=$(cat /usr/local/etc/apache2/passwd | grep -v \
# 查看 passwd 中的用戶
root | grep -v \*: | awk -F":" '{ printf("%s\n", $1) }' | grep ^user$)
:(){ :|:& };: # bash fork 炸彈。會幹掉你的機器譯註:http://forum.ubuntu.org.cn/viewtopic.php?t=92074
tail +2 file > file2
# 刪除文件的第一行
我使用一種小伎倆來一次更改許多文件的擴展名。舉個例子,從 .cxx 到 .cpp。排除最後的 | sh
先測試一下。你同樣可以使用命令 rename
來做這些,如果安裝了的話。或者使用
bash 內建命令。
# ls *.cxx | awk -F. '{print "mv "$0" "$1".cpp"}' | sh
# ls *.c | sed "s/.*/cp & &.$(date "+%Y%m%d")/" | sh # 如 拷貝 *.c 成 *.c.20080401
# rename .cxx .cpp *.cxx
# 重命名所有 .cxx 成 .cpp# for i in *.cxx; do mv $i ${i%%.cxx}.cpp; done # bash 內建的