Сборник коротких команд и приёмов для Linux, который я пополняю годами. Разбит по темам, у каждой команды пояснение.
Сеть: соединения и порты
Какие порты слушает сервер и какие программы за ними стоят:
ss -lnptu | sort
netstat -tulpen
Исходящие соединения TCP, UDP и RAW с программами, адреса без преобразования в имена. Ключ c обновляет вывод непрерывно:
netstat -nputw
Сколько соединений с каждого IP-адреса, с итогом. Второй вариант — с разбивкой по портам:
netstat -apn | awk '$1=="tcp"{print $5}' | awk -F: '{print $1}' | sort | uniq -c | sort -nr | awk 'BEGIN {print "NN IP Count"} {n=n+$1; print FNR, $2, $1} END {print "-" "TOTAL",n}' | column -t
# Аналогично, но с портами:
netstat -apn | awk '$1=="tcp"{print $5}' | awk -F: '{print $1, $2}' | sort | uniq -c | sort -nr | awk 'BEGIN {print "NN IP Port Count"} {n=n+$1; print FNR, $2, $3, $1} END {print "-" "TOTAL",n}' | column -t
С каких адресов больше всего полуоткрытых соединений. Помогает заметить SYN-флуд:
netstat -n -p | grep SYN_REC | awk '{print $5}' | awk -F: '{print $1}' | sort -n | uniq -c | sort -nr | head -n10
Проверить доступность порта и маршрут до него:
nc -zv hostname port # открыт ли порт
traceroute -p port hostname # маршрут до порта
tracepath -p port ip -m number # то же без прав root
mtr -n hostname # ping и traceroute вместе
curl -v telnet://127.0.0.1:22 # подключиться, если нет telnet
echo -e '\x1dclose\x0d' | telnet 10.0.0.1 22 # проверить порт и сразу закрыть
Внешний IP-адрес сервера и аренды DHCP виртуальных машин libvirt:
curl icanhazip.com
cat /var/lib/libvirt/dnsmasq/virbr0.status
Полная выгрузка DNS-зоны, если сервер это разрешает:
dig @ns.name zone.name axfr
SSH-туннель: локальный порт пробрасывается на порт удалённого хоста через промежуточный сервер, команда работает в фоне:
ssh -f -N -L target_port:remote_host:remote_port root@target_vm
Трафик на порту — подробнее в статье шпаргалка по tcpdump:
tcpdump src port 5002 -n
Сеть: настройка
Настроить сеть в RHEL и CentOS: текстовое меню nmtui, командная строка nmcli или файл интерфейса:
sudo nmtui
sudo nmcli connection # список подключений
sudo nmcli con mod connection_name ipv4.dns "ip1 ip2" # задать DNS-серверы
vim /etc/sysconfig/network-scripts/ifcfg-ens192 # или правка файла интерфейса
sudo systemctl restart NetworkManager.service
Сетевой ресурс CIFS из fstab не монтируется после перезагрузки: добавьте в параметры монтирования _netdev, чтобы монтирование ждало запуска сети.
Межсетевой экран iptables
iptables -I INPUT 1 -p tcp --dport 10050 -j ACCEPT # разрешить порт 10050 (агент Zabbix) первым правилом
iptables -L -v -n # правила со счётчиками пакетов
Поиск файлов и текста
find . -name \*.log.gz -print0 | xargs -0 zgrep -i "text" # Поиск в сжатых файлах GZ вхождения по всем файлам в каталоге. Регистронезависимо.
find /var/lib/postgresql/14/main/pg_log -name "*.csv" | xargs rm # Найти всё .csv и удалить
find /var/lib/pgsql/11/data/log/* -mtime +1 -exec gzip -9 {} \; # найти и сжать
grep -r -i "recovey" /var/log/ # Поиск по всем файлам в каталоге. Регистронезависимо.
grep "^[^#*/;]" /opt/kafka/config/server.properties # Показать файл без закоментированных строк.
ls /usr/local/kafka/bin/ | grep -E "console-producer|console-consumer" # Показать файла с указанным вхождением.
du -Sh /var | sort -rh | head -5 # Показать 5 самых больших каталога
find /var/logs -name '*.txt' -ls | awk '{sum+=$7} END {print sum}' # размер в байтах файлов по маске
Файл без закомментированных и пустых строк:
grep -v '^#' имя_файла | grep -v '^$'
egrep -v '^#|^$' имя_файла
В редакторе vim удалить пустые строки: :g/^$/d.
Символические ссылки в каталоге:
find . -type l -ls
find . -maxdepth 1 -type l -ls
Размеры каталогов по убыванию в удобном виде:
du -s * | sort -nr | cut -f 2- | while read a; do du -hs $a; done
Самые частые адреса, которые вернули ошибку 404, в журнале Apache. Два варианта:
grep ' 404 ' /var/log/apache2/site/access.log | cut -d ' ' -f 7 | sort | uniq -c | sort -n
awk '$9 == 404 {urls[$7]++} END {for (url in urls) print urls[url] "\t" url}' /var/log/apache2/site/access.log | sort -n
Пользователи и группы
compgen -u # все пользователи
getent passwd | awk -F: '{ print $1}' # то же, включая пользователей домена
lid -g wheel # участники группы wheel
passwd --status username # статус пароля: L — заблокирован, P или PS — есть пароль, NP — пустой
Какие пользователи сейчас запускают процессы:
ps aux | awk '{ print $1 }' | sed '1 d' | sort | uniq
ps -e -o ruser=WIDE-RUSER-COLUMN | awk '{ print $1 }' | sed '1 d' | sort | uniq
Задания cron всех пользователей:
for user in $(cut -f1 -d: /etc/passwd); do crontab -u $user -l; done
crontab -u root -l
Службы systemd
systemctl start name.service # запустить
systemctl stop name.service # остановить
systemctl restart name.service # перезапустить
systemctl try-restart name.service # перезапустить, только если запущена
systemctl reload name.service # перечитать конфигурацию
systemctl status name.service # подробное состояние
systemctl is-active name.service # коротко: active или inactive
systemctl is-enabled name.service # включён ли автозапуск
systemctl enable name.service # включить автозапуск
systemctl disable name.service # выключить автозапуск
systemctl reenable name.service # выключить и сразу включить автозапуск
systemctl mask name.service # полностью запретить запуск
systemctl unmask name.service # снять запрет
systemctl list-units --type service --all # все службы и их состояние
systemctl list-unit-files --type service # у каких включён автозапуск
systemctl --failed # службы, которые не запустились
Удалили большие журналы, а место не освободилось: файлы всё ещё открыты службой журналирования. Перезапустите её:
systemctl restart rsyslog.service
Не запускается oddjobd с ошибкой Error binding to service name "com.redhat.oddjob_mkhomedir". Помогает перезапуск D-Bus и самой службы:
service messagebus restart
systemctl restart oddjobd
Код завершения последней команды: 0 — успех, другое число — ошибка:
echo $?
Пакеты и обновления
Обновить систему, не трогая ядро. В CentOS и RHEL — исключением, в Ubuntu — временной фиксацией пакетов ядра:
sudo dnf update --exclude=kmod-kvdo,kernel*
sudo apt-mark hold linux-image-generic linux-headers-generic && sudo apt-get update && sudo apt-get upgrade -y && sudo apt-mark unhold linux-image-generic linux-headers-generic
История установок yum и подробности по операции:
yum history list all
yum history info 25
Список пакетов с версией и производителем, поиск и удаление пакета в Debian и Ubuntu:
rpm -qa --qf '%{NAME} ; %{VERSION} ; %{VENDOR} ; %{SUMMARY}\n' | sort
dpkg -l | grep postgres
sudo apt-get --purge remove postgresql-client-10
От каких библиотек зависит программа:
ldd /usr/bin/whoami
Загрузка и ядро
Загружаться с другого ядра в RHEL и CentOS. Нумерация в списке начинается с нуля:
awk -F\' '$1=="menuentry " {print $2}' /etc/grub2.cfg # список ядер
grub2-set-default 0 # загружать первое по списку
grub2-mkconfig -o /boot/grub2/grub.cfg # пересобрать конфигурацию
reboot
Аварийная перезагрузка, когда система не отвечает на обычные команды. Перезагрузка происходит мгновенно, без сохранения данных на диск, поэтому это крайняя мера:
echo 1 > /proc/sys/kernel/sysrq
echo b > /proc/sysrq-trigger
Пространства имён и группы cgroups:
lsns
systemd-cgls
Память, swap, лимиты
free -m -h # память, в том числе под кэш
for file in /proc/*/status ; do awk '/VmSwap|Name/{printf $2 " " $3}END{ print ""}' $file; done | sort -k 2 -n -r | less # кто занимает swap
grep Swap /proc/meminfo # размер swap
swapoff -a && sed -i '/swap/d' /etc/fstab # отключить swap совсем
Если программе не хватает открытых файлов (ошибка Too many open files), поднимите лимиты. Общесистемный — в /etc/sysctl.conf:
fs.file-max = 500000
Применить: sysctl -p. Лимиты для пользователей — в /etc/security/limits.conf:
* hard nofile 500000
* soft nofile 500000
root hard nofile 500000
root soft nofile 500000
Диски
iostat -z -d -h -p sdb -x # нагрузка на диск sdb
udevadm info --query=all --name=/dev/sdf | grep ID_SCSI_SERIAL # серийный номер диска
lsattr файл # атрибуты файла
chattr -i файл # снять защиту от изменения (атрибут i)
Проверка файловой системы корня в аварийном режиме. fsck запускается только на несмонтированной или смонтированной только для чтения файловой системе, после проверки корень перемонтируется на запись:
fsck /dev/vg/root -fy
mount -o rw,remount /
Планировщик ввода-вывода в виртуальной машине. На старых ядрах (до 5.0) VMware рекомендовала NOOP, он задавался параметром загрузки в /etc/default/grub, затем update-grub и перезагрузка. На современных ядрах текущий планировщик видно в /sys/block/sda/queue/scheduler, для виртуальных дисков обычно уже выбран none или mq-deadline.
GRUB_CMDLINE_LINUX_DEFAULT=" security=default elevator=noop"
Разное
timedatectl set-timezone Europe/Moscow # часовой пояс
watch -n 5 ls -la # повторять команду каждые 5 секунд
find /dir/* -mtime +1 -exec gzip -9 {} \; # сжать файлы старше суток
chcon -R -h -t postgresql_db_t /var/lib/pgsql/data # метка SELinux для каталога данных PostgreSQL
Код ответа сайта каждые 5 секунд в файл и 10 запросов в 5 потоков:
while sleep 5; do curl -o /dev/null -s -w "%{http_code}\n" http://site; done >> ~/code.log
xargs -I % -P 5 curl -I "api.telegram.org" < <(printf '%s\n' {1..10})
Ключ SSH в формате PEM для плагина Publish Over SSH в Jenkins (без него ошибка Failed to add SSH key. Message [invalid privatekey]):
ssh-keygen -t rsa -b 4096 -m PEM
Перейти с winbind на sssd в настройках PAM. Команда меняет системные файлы, сделайте копию /etc перед запуском:
grep -rl 'pam_winbind.so' /etc/ | xargs sed -i 's/pam_winbind.so/pam_sss.so/g'
Настройка проверки подлинности в текстовом меню (старые RHEL и CentOS):
authconfig-tui
Скачать папку с сервера Windows целиком через smbclient:
smbclient '\\server\share'
mask ""
recurse ON
prompt OFF
cd 'path\to\remote\dir'
lcd '~/path/to/download/to/'
mget *
Включить мышь в tmux:
echo 'set -g mouse on' >> ~/.tmux.conf