技術者になりたい何か

技術者になりたい何かの覚書的な何かです

Linuxのサーバ機をルータとして動かす

iptablesdhcpサーバでブロードバンドルータと同機能を揃える。

■方針
Linuxサーバ(Debian)にNIC増設
 →片方をWAN側、片方をLAN側にしてルータとして機能させる。
DHCPサーバ立ててIP割り振りも管理。
今まで使ってたルータ(baffalo)は無線アクセスポイントとして使用。

■今まで

baffalo(192.168.11.1)-サーバ
           -デスクトップPC数台
           -無線接続のあれこれ

■構想
Debianサーバ(192.168.11.1) -ハブ-有線接続のPC数台
                -baffalo(192.168.11.100)-無線接続のあれこれ


1.NICの設定


設定ファイルは/etc/network/interfaces
enp2s0をWAN、enp3s0をLANに設定する。
ちなみにうちの回線はCATVなので、WAN側は普通に局のdhcpから取得する設定。
enp3s0は固定で192.168.11.1を当てる。

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

#WAN
allow-hotplug enp2s0
iface enp2s0 inet dhcp

#LAN
allow-hotplug enp3s0
iface enp3s0 inet static
address 192.168.11.1
netmask 255.255.255.0
network 192.168.11.0
broadcast 192.168.11.255
gateway 192.168.11.1

 

できたらネットワーク再起動

$ sudo systemctl restart networking

反映されないこと多々あったけど、サーバ自体再起動すると反映されました。

 

2.DHCPサーバ立てる

DHCPサーバにはisc-dhcp-serverを使用。

$ sudo apt-get install isc-dhcp-server

設定ファイルは/etc/dhcp/dhcpd.conf

ネットワークは192.168.11.0
DNSはルータとして使用するサーバ自体とプロバイダ提供のもの。
割り振るレンジは192.168.11.10~192.168.11.254 にしてます。

あと常用の2台のPCは固定IPを割り振っています。

dhcpサーバ機能を提供するのはLAN側なので、インターファイスを指定します。

/etc/default/isc-dhcp-server の INTERFACESv4 でLAN側のインターファイス指定。
IPv6にも対応するならv6の方も。(今回はやりません)

$ emacs /etc/default/isc-dhcp-server

INTERFACESv4="enp3s0"

 

起動→確認→自動起動設定

$ sudo systemctl start isc-dhcp-server.service
$ sudo systemctl status isc-dhcp-server.service
● isc-dhcp-server.service - LSB: DHCP server
Loaded: loaded (/etc/init.d/isc-dhcp-server; generated; vendor preset: enabled)
Active: active (running) since Sat 2018-02-10 03:46:33 JST; 13h ago
Docs: man:systemd-sysv-generator(8)
Process: 1094 ExecStart=/etc/init.d/isc-dhcp-server start (code=exited, status=0/SUCCESS)
CGroup: /system.slice/isc-dhcp-server.service
└─1106 /usr/sbin/dhcpd -4 -q -cf /etc/dhcp/dhcpd.conf enp3s0

2月 10 17:20:30 tminserver dhcpd[1106]: DHCPINFORM from 192.168.11.16 via enp3s0: not authoritative for subnet 192.168.1
2月 10 17:20:39 tminserver dhcpd[1106]: DHCPINFORM from 192.168.11.16 via enp3s0: not authoritative for subnet 192.168.1
2月 10 17:20:47 tminserver dhcpd[1106]: DHCPINFORM from 192.168.11.16 via enp3s0: not authoritative for subnet 192.168.1

$ sudo systemctl enable isc-dhcp-server.service

 

うまく行ってれば上記のような感じ。
起動失敗したときはsystemctl status とかjournalctl -xe でエラーログ確認しましょう。


3.IPforward有効にしてiptablesの設定

IPforward有効にするには
$ sudo echo 1 > /proc/sys/net/ipv4/ip_forward

なのですが、これだと再起動時にもとに戻ってしまうので永続化。

$ emacs /etc/sysctl.conf
net.ipv4.ip_forward=1

これで再起動時も有効のままになります。

iptablesの設定(余計なのが一部入ってるかも)
いちいち手打ちにすると大分大変なので、シェルスクリプトにしておいて実行するのが吉。
saveしといてrestoresてもいいけれども。

WANをenp2s0
LANをenp3s0
WAN側IPはプロバイダに割り振られてるので、ip a の出力からうまいことIPを切り出す。
LAN側IPは固定で192.168.11.1

初期化

デフォルトルール
・OUTPUT,INPUT,FORWARDをDROP,LAN側へのINPUTを許可。

WAN側にてプライベートIPへの通信をDROP

すでに確立してる通信を許可

LAN側のFORWARDを許可

NATでMASQUERADE

loとの通信を許可

ICMP(ping)を許可

LOGに記録する色々

多分、割と最低限でセキュリティ的にはもう少し詰めたほうがいいと思われ。
あと、もしかしたら必要な通信を拒否してるかもしれない。

状態確認。

$ sudo iptables -nvL
Chain INPUT (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
31038 2676K ACCEPT all -- enp3s0 * 0.0.0.0/0 0.0.0.0/0
0 0 DROP all -- enp2s0 * 192.168.0.0/16 0.0.0.0/0
0 0 DROP all -- enp2s0 * 172.16.0.0/12 0.0.0.0/0
1222 404K DROP all -- enp2s0 * 10.0.0.0/8 0.0.0.0/0
26 3532 ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- lo * 0.0.0.0/0 0.0.0.0/0 state NEW
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 0
9 365 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8
1 60 ACCEPT tcp -- * * 0.0.0.0/0 0.0.0.0/0 tcp dpt:20022
1462 90998 LOGGING all -- * * 0.0.0.0/0 0.0.0.0/0

Chain FORWARD (policy DROP 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- enp2s0 * 192.168.0.0/16 0.0.0.0/0
0 0 DROP all -- enp2s0 * 172.16.0.0/12 0.0.0.0/0
0 0 DROP all -- enp2s0 * 10.0.0.0/8 0.0.0.0/0
689K 394M ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
21449 10M ACCEPT all -- enp3s0 * 0.0.0.0/0 0.0.0.0/0
0 0 LOGGING all -- * * 0.0.0.0/0 0.0.0.0/0

Chain OUTPUT (policy DROP 2539 packets, 659K bytes)
pkts bytes target prot opt in out source destination
9520 1002K ACCEPT all -- * * 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
0 0 ACCEPT all -- * lo 0.0.0.0/0 0.0.0.0/0 state NEW
0 0 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 0
6 288 ACCEPT icmp -- * * 0.0.0.0/0 0.0.0.0/0 icmptype 8

Chain LOGGING (2 references)
pkts bytes target prot opt in out source destination
42 1708 LOG all -- * * 0.0.0.0/0 0.0.0.0/0 limit: avg 3/hour burst 5 LOG flags 0 level 4 prefix "DROP:"
1462 90998 DROP all -- * * 0.0.0.0/0 0.0.0.0/0

一旦はこれでルータとして動くようになりました。


4.今まで使ってたbaffaloのルータを無線アクセスポイントとして使う

無線APとして使うには、ROUTER→BRIDGEにすればよい。
これでルータ機能、DHCP機能などなどが止まって、無線LAN中継機になります。
あと、有線のWANポートもLANポートもすべてLANポートとして動くようになります。
よって、無線の中継機能付きハブになると思って良さげ。

BRODGEモードに変更して適当なポートにルータにしたサーバからのケーブルを接続。
ROUTERモードのときは192.168.11.1だったけど、BRIDGEモードにすると192.168.11.100になるので、
ブラウザからアクセスして必要なら設定。

今回はROUTER→BRIDGEに切り替えて接続するだけで、今までの設定のまま無線APとして動くようになってくれました。


ちなみに今気づいたけど、この設定したサーバ機から名前解決ができていない。(LAN内の他の端末からはおk

$ ping 8.8.8.8
PING 8.8.8.8 (8.8.8.8) 56(84) bytes of data.
64 bytes from 8.8.8.8: icmp_seq=1 ttl=57 time=15.3 ms
64 bytes from 8.8.8.8: icmp_seq=2 ttl=57 time=14.0 ms
64 bytes from 8.8.8.8: icmp_seq=3 ttl=57 time=15.6 ms
^C
--- 8.8.8.8 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2002ms
rtt min/avg/max/mdev = 14.078/15.003/15.600/0.678 ms

$ ping google.com
ping: google.com: 名前解決に一時的に失敗しました

 

 

うーむ。。。

 

 

2/19ついき

OUTPUTのデフォルトをDROPにしてたから、個別にport 53への通信を許可するか、

OUTPUTを許可するかどっちかしないとそりゃ通りませんよね。

 

個別許可の場合は

iptables -A OUTPUT -p udp --dport 53 -j ACCEPT

を追記、

OUTPUT全許可の場合は

iptables -P OUTPUT DROP

iptables -P OUTPUT ACCEPT

にすればおk

 

postfixでroot宛メールをgmailに転送

サーバに溜まっていくroot宛のメールをgmailに転送するための設定を入れてみることにします。

環境はDebian 9.3。メールサーバはpostfixを使用。

■必要パッケージインストール

$ sudo apt install postfix bsd-mailx libsasl2-modules

postfix自動起動有効に。

$ sudo systemctl enable postfix

Synchronizing state of postfix.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable postfix

 

postfixのmain.cfで設定

$ emacs /etc/postfix/main.cf
relayhost = [smtp.gmail.com]:587
smtp_use_tls = yes
smtp_sasl_auth_enable = yes
smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
smtp_sasl_tls_security_options = noanonymous
smtp_tls_CApath = /etc/pki/tls/certs/ca-bundle.crt


■パスワードファイルとハッシュファイルの作成

パスワードファイルはsmtp_sasl_password_mapsで指定したもの。
別に名前はこれじゃなくても良い。

$ emacs /etc/postfix/sasl_passwd
[smtp.gmail.com]:587 <username>@gmail.com:<password>

sasl_passwdは平文でgmailのアカウントとパスワードを保存しているので、
root以外読み取れないようにアクセス権変更

$ sudo chmod 600 /etc/postfix/sasl_passwd

ハッシュファイル作成

$ sudo postmap /etc/postfix/sasl_passwd

設定ファイルの状態

$ ls -la /etc/postfix/
合計 148
drwxr-xr-x 5 root root 4096 2月 9 20:31 .
drwxr-xr-x 104 root root 4096 2月 9 21:00 ..
-rw-r--r-- 1 root root 43 1月 18 19:56 dynamicmaps.cf
drwxr-xr-x 2 root root 4096 9月 27 13:56 dynamicmaps.cf.d
-rw-r--r-- 1 root root 231 2月 9 20:25 main.cf
-rw-r--r-- 1 root root 27130 1月 18 19:56 main.cf.proto
-rw-r--r-- 1 root root 4416 9月 27 13:56 makedefs.out
-rw-r--r-- 1 root root 6068 1月 18 19:56 master.cf
-rw-r--r-- 1 root root 6068 1月 18 19:56 master.cf.proto
-rwxr-xr-x 1 root root 29446 9月 27 13:56 post-install
-rw-r--r-- 1 root root 10170 9月 27 13:56 postfix-files
drwxr-xr-x 2 root root 4096 1月 18 19:56 postfix-files.d
-rwxr-xr-x 1 root root 9502 9月 27 13:56 postfix-script
drwxr-xr-x 2 root root 4096 9月 27 13:56 sasl
-rw------- 1 root root 48 2月 9 20:42 sasl_passwd ★
-rw------- 1 root root 12288 2月 9 20:42 sasl_passwd.db ★

postfix 再起動(or 再読込)

$sudo systemctl restart postfix

■動作確認①

テストメール送信

$ echo "Test message" | mail <username>@gmail.com

→自分のgmailに届けばおk。

ログは/var/log/mail.logに出るので、うまく行かなかったときは確認すると良い

下はうまく行かなかったとき。

アカウント or パスワード間違えてて「535-5.7.8 Username and Password not accepted.」

$ sudo tail -50 /var/log/mail.log
~~抜粋~~
Feb 9 20:37:53 tminserver postfix/pickup[8922]: 9E8B93E0068: uid=1000 from=<tmin>
Feb 9 20:37:53 tminserver postfix/cleanup[8940]: 9E8B93E0068: message-id=<20180209113753.9E8B93E0068@tminserver.localdomain>
Feb 9 20:37:53 tminserver postfix/qmgr[8923]: 9E8B93E0068: from=<tmin@tminserver.localdomain>, size=406, nrcpt=1 (queue active)
★Feb 9 20:37:53 tminserver postfix/smtp[8942]: connect to smtp.gmail.com[2404:6800:4008:c04::6c]:587: Network is unreachable
★Feb 9 20:37:55 tminserver postfix/smtp[8942]: 9E8B93E0068: SASL authentication failed; server smtp.gmail.com[108.177.97.108] said: 535-5.7.8 Username and Password not accepted. Learn more at?535 5.7.8 https://support.google.com/mail/?p=BadCredentials x15sm6410111pff.55 - gsmtp
Feb 9 20:37:57 tminserver postfix/smtp[8942]: 9E8B93E0068: to=<mail@example.com>, relay=smtp.gmail.com[108.177.97.109]:587, delay=3.6, delays=0.11/0.06/3.4/0, dsn=4.7.8, status=deferred (SASL authentication failed; server smtp.gmail.com[108.177.97.109] said: 535-5.7.8 Username and Password not accepted. Learn more at?535 5.7.8 https://support.google.com/mail/?p=BadCredentials n1sm5159052pge.19 - gsmtp)
Feb 9 20:43:10 tminserver postfix[10439]: Postfix is running with backwards-compatible default settings

今度はうまくいったとき。

dsn=2.0.0, status=sent (250 2.0.0 OK 1518176614 i3sm4710337pgs.63 - gsmtp)

Feb 9 20:43:31 tminserver postfix/pickup[10621]: B9D563E006B: uid=1000 from=<tmin>
Feb 9 20:43:31 tminserver postfix/cleanup[10738]: B9D563E006B: message-id=<20180209114331.B9D563E006B@tminserver.localdomain>
Feb 9 20:43:31 tminserver postfix/qmgr[10622]: B9D563E006B: from=<tmin@tminserver.localdomain>, size=406, nrcpt=1 (queue active)
Feb 9 20:43:31 tminserver postfix/smtp[10626]: connect to smtp.gmail.com[2404:6800:4008:c04::6c]:587: Network is unreachable
★ Feb 9 20:43:34 tminserver postfix/smtp[10626]: B9D563E006B: to=<mail@example.com>, relay=smtp.gmail.com[74.125.204.108]:587, delay=3.1, delays=0.08/0/2.1/0.92, dsn=2.0.0, status=sent (250 2.0.0 OK 1518176614 i3sm4710337pgs.63 - gsmtp)
Feb 9 20:43:34 tminserver postfix/qmgr[10622]: B9D563E006B: removed

■root宛のメールを転送する設定。

aliaseの設定

$ cat /etc/aliases
# /etc/aliases
mailer-daemon: postmaster
postmaster: root
nobody: root
hostmaster: root
usenet: root
news: root
webmaster: root
www: root
ftp: root
abuse: root
noc: root
security: root
root: tmin

rootのところにアカウントを入れる。

$ emacs /etc/aliases
root:<username>@gmail.com

設定反映

$ sudo newaliases

■動作確認②

$ sudo echo test | mail root

gmailにtestでメールが届けばおk。

うまく行っていれば、サーバからのroot宛のmailも転送されてくるはず。

 

てきすとすとりーむ2

テキスト処理系2回目。
テキストデータを加工するための色々。
組み合わせて使うとなんだか色々できる。

■uniq

重複している行をまとめて出力する。
入力するテキストストリームは予めソートしておく必要がある。
ので、多くの場合sortと併用される。

ログの集計とかに便利。nginxとかapacheアクセスログから簡易アクセス解析とかもできます。

というわけでsshdのFailedを集計してみます。先日やったけども。

こういうログから存在しているユーザ名でのログイン失敗ログからIPを抜き出して集計。
(対象ログ→/var/log/auth.log)

Dec 3 00:01:10 tminserver sshd[29952]: Failed password for root from 58.242.83.26 port 41788 ssh2
Dec 3 00:01:13 tminserver sshd[29952]: Failed password for root from 58.242.83.26 port 41788 ssh2
Dec 3 00:01:15 tminserver sshd[29952]: Failed password for root from 58.242.83.26 port 41788 ssh2
Dec 3 00:01:17 tminserver sshd[29952]: Failed password for root from 58.242.83.26 port 41788 ssh2
Dec 3 00:12:15 tminserver sshd[30090]: Failed password for invalid user admin from 103.207.37.155 port 507
05 ssh2
Dec 3 00:12:23 tminserver sshd[30092]: Failed password for invalid user support from 103.207.37.155 port 6
3144 ssh2
Dec 3 00:12:32 tminserver sshd[30099]: Failed password for invalid user admin from 103.207.37.155 port 620
87 ssh2

パターン①rootでログイン失敗しているアクセス元IPの集計

集計期間は12/3-6 →grep 'Dec [3-6]'
失敗してるのを抜き出す →grep 'Failed'
存在しないユーザ名での失敗ははじく→grep -v 'invalid'
IPのカラム(フィールド)を抜き出す→ cut -d ' ' -f 12
抜き出したIPをソート → sort
ソートしたIPの重複分削除するけどそれぞれの件数(行数?)はカウントする → uniq -c
カウントした結果が1カラム目に出るので、多い方から順にソート → sort -nr

$ sudo grep 'Dec [3-6]' /var/log/auth.log | grep 'Failed' | grep -v 'invalid' | cut -d ' ' -f 12 | sort | uniq -c | sort -nr
54381 58.242.83.26
15564 42.7.26.91
156 193.201.224.218
21 103.207.37.155
14 103.99.1.187
14 103.207.37.154
12 92.247.83.86
12 42.62.51.53
12 103.99.0.199
10 181.214.87.4
6 91.126.205.238
6 90.226.61.158
6 87.123.137.84
6 84.135.151.34
6 83.233.45.72
6 69.165.46.170
6 69.131.92.126
6 61.153.20.84
6 60.179.11.32
6 60.173.82.156
6 60.165.208.28
6 59.15.210.188
6 59.120.249.139
6 46.72.18.89
6 41.82.138.10
6 39.71.158.158
6 38.108.61.214


~~~以下略~~~~

 

パターン②存在しないユーザで入力されているユーザ名を集計。

集計期間は12/3-6 →grep 'Dec [3-6]'
失敗してるのを抜き出す →grep 'Failed'
存在しないユーザ名での失敗を抜き出す →grep 'invalid user'
入力されたユーザ名のカラム(フィールド)を抜き出す→ cut -d ' ' -f 12
抜き出したユーザ名をソート → sort
ソートしたユーザ名の重複分削除するけどそれぞれの件数(行数?)はカウントする → uniq -c
カウントした結果が1カラム目に出るので、多い方から順にソート → sort -nr

$ sudo grep 'Dec [3-6]' /var/log/auth.log | grep 'Failed' | grep 'invalid user' | cut -d ' ' -f 12 | sort | uniq -c | sort -nr
446 admin
52 user
36 ubnt
33 test
32 pi
31 support
27
25 ftp
22 guest
22 ftpuser
21 service
20 1234
20 0
14 user1
14 adm
14 111111
13 super
13 operator
13 default
10 manager
10 22
9 sysadmin
9 nagios
9 a
8 webmaster
8 tomcat
8 scan
8 postgres
8 monitor
8 git
8 fax
8 apache
8 123321
7 www
7 usuario
7 report
7 mother
7 matsumoto
7 auction
7 administrator
7 123
~~~以下省略~~~~

 
つかpiって誰だよ

■wc

ファイルの行数、単語数、文字数を表示。
数えるのがめんどい時に便利。

オプション
-c 文字数(バイト数)を表示
-l 行数を表示
-w 単語数を表示

単純に大きいファイルの時に行数見たりとか、
grepの検索結果をwc -l に渡して件数カウントしたりする時とかに使える。

上記sshアタックのログの場合で、rootでログインしようとして失敗しているログの件数(12/3~12/6)


$ sudo grep 'Dec [3-6]' /var/log/auth.log.1 | grep 'Failed' | grep 'root' |wc -l
70539

■pr

印刷前の整形によく使うらしい。
コマンドラインから印刷・・・?

-l でヘッダ・フッタを含むページの行数を指定。+1:2で1ページ目から2ページ目まで。

$ pr -l 25 +1:2 dpkg.log


2017-12-13 18:16 dpkg.log 1 ページ


2017-12-02 08:56:42 startup archives unpack
2017-12-02 08:57:16 upgrade curl:amd64 7.38.0-4+deb8u7 7.38.0-4+deb8u8
2017-12-02 08:57:16 status half-configured curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status unpacked curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status half-installed curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status triggers-pending man-db:amd64 2.7.0.2-5
2017-12-02 08:57:17 status half-installed curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status unpacked curl:amd64 7.38.0-4+deb8u8
2017-12-02 08:57:17 status unpacked curl:amd64 7.38.0-4+deb8u8
2017-12-02 08:57:18 upgrade libcurl3:amd64 7.38.0-4+deb8u7 7.38.0-4+deb8u8
2017-12-02 08:57:18 status half-configured libcurl3:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:18 status unpacked libcurl3:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:18 status half-installed libcurl3:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:18 status half-installed libcurl3:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:18 status unpacked libcurl3:amd64 7.38.0-4+deb8u8

 

 

 

2017-12-13 18:16 dpkg.log 2 ページ


2017-12-02 08:57:18 status unpacked libcurl3:amd64 7.38.0-4+deb8u8
2017-12-02 08:57:19 upgrade libcurl3-gnutls:amd64 7.38.0-4+deb8u7 7.38.0-4+deb8u8
2017-12-02 08:57:19 status half-configured libcurl3-gnutls:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:19 status unpacked libcurl3-gnutls:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:19 status half-installed libcurl3-gnutls:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:19 status half-installed libcurl3-gnutls:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:20 status unpacked libcurl3-gnutls:amd64 7.38.0-4+deb8u8
2017-12-02 08:57:20 status unpacked libcurl3-gnutls:amd64 7.38.0-4+deb8u8
2017-12-02 08:57:20 upgrade bzr:all 2.6.0+bzr6595-6 2.6.0+bzr6595-6+deb8u1
2017-12-02 08:57:20 status half-configured bzr:all 2.6.0+bzr6595-6
2017-12-02 08:57:20 status unpacked bzr:all 2.6.0+bzr6595-6
2017-12-02 08:57:20 status half-installed bzr:all 2.6.0+bzr6595-6
2017-12-02 08:57:20 status half-installed bzr:all 2.6.0+bzr6595-6
2017-12-02 08:57:20 status unpacked bzr:all 2.6.0+bzr6595-6+deb8u1
2017-12-02 08:57:21 status unpacked bzr:all 2.6.0+bzr6595-6+deb8u1

 

これリダイレクトかなんかで新しいファイルに出力すると印刷時にきれいになるという事かな?
ぶっちゃけ使う場面がいまいち・・・

■fmt

テキストを決められた桁に整形する。

オプション
-w 一行の幅を設定

$ head -5 /var/log/dpkg.log
2017-12-02 08:56:42 startup archives unpack
2017-12-02 08:57:16 upgrade curl:amd64 7.38.0-4+deb8u7 7.38.0-4+deb8u8
2017-12-02 08:57:16 status half-configured curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status unpacked curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status half-installed curl:amd64 7.38.0-4+deb8u7


↑のようなのを最大幅40で整形すると・・・

$ head -5 /var/log/dpkg.log | fmt -w 40
2017-12-02 08:56:42 startup archives
unpack 2017-12-02 08:57:16 upgrade
curl:amd64 7.38.0-4+deb8u7
7.38.0-4+deb8u8 2017-12-02
08:57:16 status half-configured
curl:amd64 7.38.0-4+deb8u7 2017-12-02
08:57:17 status unpacked curl:amd64
7.38.0-4+deb8u7 2017-12-02 08:57:17
status half-installed curl:amd64
7.38.0-4+deb8u7

とはいえなかなかうまいとこで切れてくれないです。行が変に結合して余計読みにくい。
こういう時は-sオプション付けて行結合しないように指定してやると・・・

$ head -5 /var/log/dpkg.log | fmt -s -w 40
2017-12-02 08:56:42 startup archives
unpack
2017-12-02 08:57:16 upgrade curl:amd64
7.38.0-4+deb8u7 7.38.0-4+deb8u8
2017-12-02 08:57:16 status
half-configured curl:amd64
7.38.0-4+deb8u7
2017-12-02 08:57:17 status unpacked
curl:amd64 7.38.0-4+deb8u7
2017-12-02 08:57:17 status
half-installed curl:amd64
7.38.0-4+deb8u7

さっきよりましになりましたね。

■expand

テキストファイル内のタブをスペースに変換

オプション 
-i 行頭のタブのみ変換
-t タブ幅 タブ幅を設定する

■unexpand

行頭にある連続した空白をタブに変換

オプション
-a 行頭以外の空白も変換
-t タブ幅 タブ幅指定(デフォルトでは8ケタ)

インデント付けるときの変換とかには便利かもしれない
あと空白→タブに一括返還しといてエクセル貼り付けとか?

■xargs

これはテキストストリームに入れていいのかよくわからないけども。
標準入力から受け取った文字列を引数に指定して、与えられたコマンドを実行。
引数の数が多すぎた場合でも良きに計らってくれる気が利くやつ。
大量のログ調査とかでうまい事やってくれてるのがこいつの仕業である。

$ find -type f -name "*log*"

logがファイル名に含まれるファイルをカレントディレクトリから検索。

これをxargs でcatにつなぐと、cat の引数として上記ファイルが全てうまい事引き渡される。
ので、順次catで展開されていく。後ろに| grep 'hoge' をつければその結果からhogeが含まれる行を抽出してくれる。

$ find -type f -name "*log*" | xargs cat | grep "hoge"

引き渡すコマンド次第では引数となるファイルが多すぎるとエラーを吐いたりすることがある。
その辺上手くやってくれるのがxargs。
xargs [コマンド] のコマンド部分の引数として前の結果を渡すので、コマンド次第ではうまくいかないときもなきにしもあらず。


$ sudo find /var/log -type f -name 'mail.log.?.gz'
/var/log/mail.log.2.gz
/var/log/mail.log.4.gz
/var/log/mail.log.3.gz

この出力されたmail.log[2-4].gz をxargsでzcatに渡してgrepをかけると

$ sudo find /var/log -type f -name 'mail.log.?.gz' | xargs sudo zcat | grep 'status=sent'
Jul 7 17:33:15 tminserver postfix/local[6448]: 0E4B540D99: to=<tmin@tminserver.localdomain>, orig_to=<root>, relay=local, delay=0.56, delays=0.33/0.09/0/0.15, dsn=2.0.0, status=sent (delivered to mailbox)

3つのファイルが順次に後ろのzcatに渡される→grep status=sentで。
ちなみに下記のコマンドと一緒になる。(最初のカラムにファイルフルパスが出るかどうか)

$ sudo zgrep 'status=sent' /var/log/mail.log.?.gz
/var/log/mail.log.3.gz:Jul 7 17:33:15 tminserver postfix/local[6448]: 0E4B540D99: to=<tmin@tminserver.localdomain>, orig_to=<root>, relay=local, delay=0.56, delays=0.33/0.09/0/0.15, dsn=2.0.0, status=sent (delivered to mailbox) 


上手く使えば○○日以上たったファイルを前部圧縮とか全部退避、とかもできる。

Sponsored Link