Backlight

Mam laptop, ten z WindowMakerem, na którym chcę bardzo precyzyjnie ustawiać jasność ekranu. Zabieram go często w trasę, więc zależy mi na baterii i oczy będą mi potrzebne jeszcze przez kilka lat. Na klikalnych ustawianiach różnica pomiędzy poziomami jasności jest dosyć duża i dlatego używam małego skryptu:

#!/usr/bin/bash
echo -n "Jest: "
cat /sys/class/backlight/radeon_bl0/brightness
echo -n "Ustaw na: "
read bright
sudo echo "$bright" > /sys/class/backlight/radeon_bl0/brightness
echo " "

Niestety jest on specyficzny dla mojej karty graficznej, ale różnica tkwi wyłącznie w katalogu radeon_bl0, który u Ciebie może być inny. Jest w nim, między innymi, plik brightness zawierający liczbę od 0 do 254 (lub od 1 do 255), który odpowiada za – niespodzianka – jasność ekranu. Skrypt trzeba uruchamiać z sudo, lub jako root, ale terminal mam pod ręką.

Dodatkowo, wieczorami lubię ograniczyć ilość niebieskiego na ekranie. Jestem przyzwyczajony do Redshift na moim głównym komputerze roboczym, więc używam małego „zamiennika” na laptopie:

xgamma -bgamma 0.8

Jadąc pociągiem, czy autobusem po 19:00, a jesienią i zimą znacznie wcześniej, daje duży komfort pracy.

Blokowanie IPv6

Niektórzy dostawcy (jak OVH) uszczęśliwiają mnie na siłę, nadając nowy adres IPv6 dla serwerków. Wspominałem już o podstawach konfiguracji firewalla na VPSie, ale sprawa dotyczyła IPv4. Jeżeli wyłączamy usługę firewalld i chcemy się pobawić firewallem, warto zadbać również o ruch na adresie z nowego zakresu.

Jak ja to robię? Dropuję wszystko jak leci. 🙂 Nie jestem póki co zainteresowany, ale nie chcę też, by ktoś zrobił mi krzywdę, łącząc się przez słabiej zabezpieczone porty. Na Fedorze, Red Hacie i wszystkich pochodnych, mamy dwie pomocne usługi: iptables oraz ip6tables. Dzisiaj zajmiemy się tą drugą.

Najpierw zaglądamy do pliku /etc/sysconfig/ip6tables i komentujemy wszystkie linijki. Końcówka mojego pliku wygląda tak:

*filter
:INPUT DROP [0:0]
:FORWARD DROP [0:0]
:OUTPUT DROP [0:0]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -i lo -j ACCEPT
COMMIT

Gdyby jakiś lokalny proces bardzo musiał korzystać z ipv6, to przeszkadzać mu nie będę 🙂 , ale wszystkie zewnętrzne połączenia są zamknięte. Pozostało jeszcze ustawienie usługi w systemd:

sudo systemctl enable ip6tables
sudo systemctl start ip6tables

oraz sprawdzenie regułek:

sudo ip6tables -L

Możemy już pomachać IPv6 na pożegnanie.

bashrc

Bashrc to prosty skrypt interpretowany zaraz po zalogowaniu się. Prościej się nie da, dopóki nie wrócimy do autoexec.bat. Można ustawiać w nim przeróżne aliasy oraz krótkie polecenia, które i tak wpisywałbym zaraz po zalogowaniu. Fragment mojego pliku:

alias rm='rm -i'
alias cp='cp -i'
alias mv='mv -i'
alias 'dir'='ls --sort=extension --color -h -al'
alias 'top'='htop --user=lukasz --sort=PERCENT_CPU --delay=25'
alias vi='vim'
alias sjava='/usr/java/default/bin/java -jar'
alias xterm='xterm -bg 'black' -fg 'grey' -fa 'Monospace' -fs 14'
alias men='LANG=C man'

Trzy pierwsze aliasy są dla mnie zawsze obowiązkowe, żebym nie usunął, ani nie nadpisał sobie przypadkiem ważnych plików i katalogów. Do dira jestem przyzwyczajony i pisałem już o tym. Xterma używam czasami do kompilacji i budowaniu pakietów, gdzie nie zależy mi na super poprawnym wyświetlaniu wszystkich komunikatów, ale od czasu do czasu rzucam okiem co się dzieje. Kilka parametrów pozwala widzieć cokolwiek na dużym monitorze.

Co jednak w sytuacji, kiedy chcę topa, a nie htopa? Bash automatycznie uruchamia htopa i niby nic nie można na to poradzić, oprócz „zunaliasowania” potrzebnego mi programu. Wystarczy uruchomić program z pełną ścieżką, np. /usr/bin/top. Skoro nie ma do tego aliasu w bashrc, zostanie zwyczajnie uruchomiony top.

Ostatnie co mam, ale wam nie pokażę, to aliasy w rodzaju

alias frytka='ssh ADRES_IP'

, bo zapamiętanie adresów IP to dla mnie kosmos. 🙂 Jedyne, co jestem w stanie zapamiętać, to 8.8.8.8, którego i tak nie używam, ale przydaje się od czasu do czasu.

Własne repo yum/dnf

Pisałem kiedyś tam o specu dla jednoplikowego programu. Pakiet RPM to oczywiście fajna sprawa, ale trzeba go jakoś rozprowadzić po różnych komputerach i pilnować, żeby był aktualny. Żeby być szczerym, to dla jednego pliku pewnie użyłbym syncthinga i umieścił locate_plus w ~/bin, ale skoro mamy już pakiet, to coś z nim zróbmy.

Pakiet jest na razie w katalogu ~/rpmbuild/RPMS/noarch, ale skopiujmy go do ~/repozytorium, żeby odizolować gotowy plik od naszych kolejnych eksperymentów. Potrzebujemy programu o nazwie createrepo, więc go zainstalujmy

dnf install createrepo

Dla fanów RHELa i centosa zamiast dnf używamy yum. Potem wystarczy już tylko

cd ~/repozytorium
createrepo --update .

Repo jest już gotowe, ale dnf/yum nic o nim nie wie. Idziemy do katalogu /etc/yum.repos.d i wklejamy tam taki plik:

cat /etc/yum.repos.d/moje.repo 
[moje]
name=moje
baseurl=file:///home/jankowalski/repozytorium/
enabled=1
gpgcheck=0
skip_if_unavailable=True

O co tu chodzi? Po kolei:

  • [moje] to skrócona nazwa repozytorium,
  • name= to długa i ładna nazwa, na przykład moje 🙂 , lub Moje Najlepsze Repozytorium,
  • baseurl to ścieżka do plików, która najczęściej jest jakimś ftpem, ale my jeszcze ftpa nie mamy,
  • enabled odpowiada za domyślne przeszukiwanie repozytorium podczas instalacji i aktualizacji pakietów,
  • gpgcheck ustawiłbym na 1, gdyby pakiet był podpisany cyfrowo,
  • skip_if_unavaible to fajne ustawienie pozwalające dnfowi (oraz yumowi) na ignorowanie repozytorium jeżeli akurat nie ma do niego dostępu.

No i dobra, pakiety są dostępne:

dnf list *locate_plus*
moje 620 kB/s | 941 B 00:00
Dostępne pakiety
locate_plus.noarch 0.1-1.fc23 moje

Chroot i /dev

Napiszę to tobie tutaj, bo ciągle o tym zapominam.

mkdir /mnt/foo
mount -t ext4 /dev/sda1 /mnt/foo
mount --bind /dev /mnt/foo/dev
chroot /mnt/foo

Czasami potrzebuję dostać się do totalnie padniętego systemu i bez chroota się nie da. Ostatnimi czasy niektóre programy (jak dnf) wymagają generatora liczb losowych, który siedzi sobie w /dev i można go sobie „pożyczyć” z uruchomionego systemu: płytki live z instalką Fedory, pendrajwa, System Rescue CD, itd…

Wybieramy Javę

Java to mały koszmarek. Nie było tak źle, póki mieliśmy Suna, ale od czasów Oracle trochę się pomieszało. Jedno chce openjdk, drugie Oracle, trzecie JRE, czwart JDK, piąte działa szybciej na jednej, a szóste zawiesza się na trzeciej. 🙂

W pewnych innych przypadkach zrobilibyśmy po prostu virtualenva, ale Java tak nie umie. O ile twórca programu nie zrobił małego skryptu pilnującego wersji Javy, która uruchamia jego program, trzeba zadbać o to samemu. Pewnym rozwiązaniem jest zrobić aliasy w bashu, co wystarczy do uruchamiania JARów, ale na Eclipse jest to za mało:

alias sjava='/usr/java/default/bin/java -jar'

Powyższe znacznie ułatwia uruchamianie małych programików z JRE pobranego ze stronki www.java.com. Jednak wspomniamy Eclipse… Swego czasu był parametr służący do wybierania JDK, ale komuś się nie podobał i go usunęli. Zostajemy więc z czysto linuksowym sposobem na wybieranie wersji binarki, czyli alternatives. Tak to się robi:

sudo update-alternatives --install "/usr/bin/javac" "javac" "/home/lukasz/.AndroidStudio2.0/java/jdk1.8.0_77/bin/javac" 1
sudo update-alternatives --install "/usr/bin/java" "java" "/home/lukasz/.AndroidStudio2.0/java/jdk1.8.0_77/bin/java" 1

W moim przypadku skopiowałem sobie całe JDK od Oracle do katalogu ~/.AndroidStudio2.0, żeby mieć wszystko w jednym miejscu. Stary Eclipse też tam siedzi. Jest więc niezły bałagan (5689 directories, 35516 files), ale mogę sobie zrobić archiwum gzipem i jest kopia robocza wszystkiego.

Wracając do tematu: co właściwie daje użycie alternatives? Tworzy dowiązania w katalogu /etc/alternatives, z którymi musimy teraz dojść do ładu:

ls -al /etc/alternatives/ | grep java
lrwxrwxrwx.   1 root root    56 04-24 10:00 java -> /home/lukasz/.AndroidStudio2.0/java/jdk1.8.0_77/bin/java
lrwxrwxrwx.   1 root root    57 04-24 10:00 javac -> /home/lukasz/.AndroidStudio2.0/java/jdk1.8.0_77/bin/javac
lrwxrwxrwx.   1 root root    62 04-16 19:06 jre_1.8.0 -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.77-1.b03.fc23.x86_64/jre
lrwxrwxrwx.   1 root root    62 04-16 19:06 jre_1.8.0_exports -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.77-1.b03.fc23.x86_64/jre
lrwxrwxrwx.   1 root root    66 04-16 19:06 jre_1.8.0_openjdk_exports -> /usr/lib/jvm-exports/java-1.8.0-openjdk-1.8.0.77-1.b03.fc23.x86_64
lrwxrwxrwx.   1 root root    62 04-16 19:06 jre_openjdk -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.77-1.b03.fc23.x86_64/jre
lrwxrwxrwx.   1 root root    62 04-16 19:06 jre_openjdk_exports -> /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.77-1.b03.fc23.x86_64/jre

Postaramy się za chwilę to opanować. Służy do tego program update-alternatives:

sudo update-alternatives --config javac
sudo update-alternatives --config java

Jest on „pseudograficzny”. Wystarczy wpisać liczbę odpowiadającą preferowanym przez nas javac oraz java, nacisnąć enter i program poprawi dowiązania w /etc/alternatives. Eclipse będzie się w końcu uruchamiał z Javy Oracle, a nie Open JDK. Pewnym efektem ubocznym jest wolniejsze uruchamianie, ale Eclipse jest bardziej testowany na Javie od Oracle. Jeżeli chcecie programować dla Androida używając wtyczki Eclipse, to nawet nie ma innego wyjścia i trzeba używać Javy Oracle.

Ograniczanie ruchu na SSH

Otwarcie portu 22 na serwerze jest z jednej strony koniecznością, ale z drugiej po każdorazowym zalogowaniu jako root widzimy nieprzyjemny komunikat o setkach i tysiącach prób zalogowania na nasz serwer, typu

There were 4011 failed login attempts since the last successful login.

(a taki komunikat właśnie otrzymałem, na długo po zaaplikowaniu przedstawianej procedury, wyobrażacie sobie jakieś 30000 prób bez tego zabezpieczenia?)
Zwykle owe próby niewiele dają, gdyż a) wyłączyłem zdalne logowanie jako root i b) uważam, że hasło jest naprawdę niezłe 🙂 , ale generują tylko dodatkowy, niepotrzebny ruch. Czy jedynym wyjściem jest zmiana portu i powiadamianie wszystkich zainteresowanych o konieczności przestawiania ustawień w putty, czy wklepywaniu portu za każdym razem? Na krótką metę zadziała, ale boty są cwane i się prędzej czy później zorientują.
Rozwiązanie, którego mnie nauczyli, a teraz piszę wam, polega na ograniczeniu ruchu na porcie 22 z poziomu firewalla. W dystrybucjach CentOS, RHEL i Fedora jest zainstalowany firewalld i mimo kilku zalet (typu wsparcia dla dockera) jest mi zbędny, używam starego, dobrego skryptu z regułkami iptables. W tym celu wyłączam firewalld i instaluję usługi iptables:

yum install iptables-services
systemctl disable firewalld.service
systemctl mask firewalld.service
systemctl enable iptables.service

Po tej wstępnej konfiguracji czas zająć się plikiem /etc/sysconfig/iptables, którego domyślną zawartość można usunąć, lub skomentować za pomocą dopisania znaku # na początku każdej linijki. Potem dopisujemy poniżej takie oto zaklęcia:

*filter
-F
-X
-P INPUT DROP
-A INPUT -s 0/0 -m state --state RELATED,ESTABLISHED -j ACCEPT

# localhost
-A INPUT -i lo -j ACCEPT

# ping
-A INPUT -p icmp -j ACCEPT

Są to podstawowe opcje, które warto mieć na każdym serwerze. Pewną wariacją może być znak komentarza przed linijką dopuszczającą pinga, ale jeszcze nigdy nie zapingowano mi serwera na śmierć, więc ta lekcja jest jeszcze przede mną. 🙂 No fajnie, ale nie mamy tu jeszcze niczego na temat SSH. Dopisujemy więc poniżej:

# SSH
# sprawdzanie, czy ktos nie laczy sie zbyt czesto
-N trap
-A INPUT -s 0/0 -p tcp --dport 22 --syn -j trap
-A trap -m recent --name its_trap --rcheck --seconds 50 --hitcount 3 --rttl -j DROP
-A trap -m recent --name its_trap --set -j RETURN

# sprawdzanie, czy ktos nie laczy sie z tego samego miejsca
-N stoper
-A INPUT -s 0/0 -p tcp --dport 22 --syn -j stoper
-A stoper -m connlimit --connlimit-above 4 -j DROP
-A stoper -m limit --limit 2/m --limit-burst 1 -j ACCEPT

# commit na koniec
COMMIT

Co to wszystko znaczy? Zamiast standardowo wpuszczać każdy pakiet na porcie 22 licząc na to, że może to być połączenie z naszym terminalem (lub putty), co nie zdarza się przecież zbyt często, wprowadzamy pewne ograniczenia. Łańcuch trap sprawdza, czy w ciągu 50 sekund nie próbowano się połączyć więcej niż 3 razy. Oznacza to, że jeżeli trzy razy wpiszę złe hasło, będę musiał poczekać do następnych 50 sekund, by próbować ponownie. Stoper sprawdza zaś, czy w ciągu ostatnich 2 minut nie próbowano się dostać więcej niż 4 razy z tego samego komputera. W obydwu przypadkach kolejne połączenia są blokowane.

Wiąże się z tym kilka niedogodności. Po pierwsze nie otworzę sobie 10 kart terminala, żeby połączyć się 10 razy z serwerem (ale od czago jest screen, czy podobne programy). Po drugie jeżeli zapomni mi się hasła, to proces jego zgadywania będzie trwał nieco dłużej. Warto więc używać kluczy ssh i nie bawić się w hasła.

Zdaję sobie sprawę, że nie jest to może specjalnie elegancko rozpisane, nie mam się za żadnego mega specjalistę od iptables, ale daje radę i zdecydowanie zmniejsza liczbę prób logowania. Na koniec trzeba powiadomić systemd o naszym zamiarach:

systemctl stop firewalld.service
systemctl disable firewalld.service
systemctl mask firewalld.service
systemctl enable iptables.service
systemctl start iptables.service
systemctl status iptables.service

Uwaga! Bardzo starałem się nie zrobić żadnej głupiej literówki kopiując te regułki, ale z iptables nigdy nic nie wiadomo. Wklejasz na własne ryzyko. Mam nadzieję, że masz jakieś zapasowe wejście do serwera.