[LINUX] Fehlerbehebungstechniken aus (fast) nichts

Verteidigung gegen dunkle Magie Adventskalender 2019 Dies ist der Artikel am 16. Tag.

Einführung

In einigen Fällen hat sich die Schwierigkeit der Fehlerbehebung aufgrund des Fortschritts der Bereitstellungsautomatisierung, der Virtualisierung vom Containertyp und der Microservices unbeabsichtigt erhöht.

In dieser Ausgabe wird erläutert, wie Sie in diesen Fällen mit der Fehlerbehebung ** fortfahren, auch wenn Sie mit dem Zielsystem nicht vertraut sind.

Start

Sie haben die für die SSH-Anmeldung bei Ihrem Linux-Server erforderlichen Informationen erhalten und sich erfolgreich angemeldet. Es ist möglich, zum Root-Benutzer zu wechseln. Aber ** ich weiß nichts anderes als Anmeldeinformationen **.

typewriter@server:~ $ sudo su -
root@server:~ # eixt
-bash: eixt: command not found
root@server:~ # exit
logout
typewriter@server:~ $

In der Zwischenzeit erhielt ich eine mehrdeutige Anfrage per E-Mail mit dem Titel "Der Zugriff auf eine Webseite verursacht einen Fehler" und werde gebeten, zu antworten.

Lass uns weitermachen.

Techniken zur Fehlerbehebung

Die einzige Möglichkeit, Fehler von Grund auf zu beheben, besteht darin, sie herauszufinden und herauszufinden.

Finden Sie eine Anwendung

** ps ** (Weder "Docker ps" noch "pstree" werden verwendet)

Sie können auch mit dem Befehl top nach den aktuell ausgeführten Prozessen suchen, wenn viele Prozesse vorhanden sind ).

##Zeigen Sie alle Prozesse im BSD-Format / benutzerorientierten Format an
$ ps aux
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3052  3.2 19.0 1122908 89636 ?       Ssl  02:24   0:03 /usr/bin/dockerd --default-ulimit nofile=1024:4096
root      3086  0.4  4.5 1004052 21332 ?       Ssl  02:24   0:00 docker-containerd --config /var/run/docker/containerd/containerd.toml
root      3865  0.0  1.1  10632  5332 ?        Ss   02:25   0:00 nginx: master process nginx -g daemon off;
101       3914  0.0  0.5  11088  2588 ?        S    02:25   0:00 nginx: worker process

Nginx wird möglicherweise auf dem Docker-Container ausgeführt. Lass uns nachsehen.

Der beste Weg, dies zu überprüfen, ist die Verwendung von "Docker ps" oder "Docker Top CONTAINER". Es ist jedoch auch möglich, den Prozessbaum mit der Option f ( --forest) des Befehls ps anzuzeigen und anhand der Eltern-Kind-Beziehung zu überprüfen.

##Baumanzeige aller Prozesse im BSD-Format und im benutzerorientierten Format
$ ps auxf
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      3052  0.4 16.7 1122908 78684 ?       Ssl  02:24   0:05 /usr/bin/dockerd --default-ulimit nofile=1024:4096
root      3086  0.4  4.8 1005108 22660 ?       Ssl  02:24   0:04  \_ docker-containerd --config /var/run/docker/containerd/containerd.toml
root      3829  0.0  0.8   7512  4184 ?        Sl   02:25   0:00  |   \_ docker-containerd-shim -namespace moby -workdir /var/lib/docker/contain
root      3865  0.0  1.1  10632  5332 ?        Ss   02:25   0:00  |       \_ nginx: master process nginx -g daemon off;
101       3914  0.0  0.5  11088  2588 ?        S    02:25   0:00  |           \_ nginx: worker process

Es läuft auf Docker!

Suchen Sie nach Konfigurationsdateien und Protokolldateien

** Dateideskriptor **

Unter Linux (POSIX) verfügt jeder Prozess über eine Liste von Dateideskriptoren oder kurz gesagt über eine "Liste geöffneter Dateien". Dies kann durch procfs gesehen werden (obwohl in den meisten Fällen derselbe Benutzer wie der Startvorgang). Muss sein).

Werfen wir einen Blick auf den Dateideskriptor des Nginx-Prozesses.

$ sudo ls -l /proc/3865/fd
total 0
lr-x------ 1 root root 64 Dec 15 02:25 0 -> 'pipe:[16216]'
l-wx------ 1 root root 64 Dec 15 02:25 1 -> 'pipe:[16217]'
l-wx------ 1 root root 64 Dec 15 02:25 2 -> 'pipe:[16218]'
lrwx------ 1 root root 64 Dec 15 02:25 4 -> 'socket:[75443]'
lrwx------ 1 root root 64 Dec 15 02:25 5 -> 'socket:[75444]'
lrwx------ 1 root root 64 Dec 15 02:25 6 -> 'socket:[16370]'

Ich konnte keine Dateien nur mit Pipes und Sockets erhalten (abgesehen davon erlaubt Linux, dass Pipes und Sockets als spezielle Dateien behandelt werden).

Aber gib nicht auf. [Der Dateideskriptor des Prozesses wird als "0" als Standardeingabe (stdin), "1" als Standardeingabe (stdout) und "2" als Standardfehlerausgabe (stderr) bestimmt](https: //linuxjm.osdn. Versuchen wir unter jp / html / LDP_man-pages / man3 / stdin.3.html # lbAD), die Standardausgabe mit cat zu saugen.

$ sudo cat /proc/3865/fd/1
##(Hier auf die Webseite zugreifen)
xxx.xx.xxx.xxx - - [15/Dec/2019:06:03:51 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.108 Safari/537.36" "-"
## ( Ctrl+Hör auf mit der C-Taste zu saugen)
^C
$ 

Das Zugriffsprotokoll von Nginx wurde veröffentlicht. Das Aufteilen von Protokollen auf die Standardausgabe ist eine orthodoxe Methode zum Betreiben eines Containers.

Wenn es in eine Datei gedruckt wird, sollte der Pfad wie folgt angezeigt werden:

$ sudo ls -l /proc/11178/fd
Insgesamt 0
lrwx------1 Wurzel Wurzel 64 15. Dezember 14:35 0 -> /dev/null
lrwx------1 Wurzel Wurzel 64 15. Dezember 14:35 1 -> /dev/null
l-wx------1 Wurzel Wurzel 64 15. Dezember 14:35 2 -> /var/log/nginx/error.log
l-wx------1 Wurzel Wurzel 64 15. Dezember 14:35 44 -> /var/log/nginx/access.log

strace,kill

Der Speicherort der Konfigurationsdatei ist noch nicht bekannt. Da es sich um Nginx handelt, ist es * fast * sicher, dass es / etc / nginx / ist, aber tun wir so, als ob wir es nicht wissen.

Der Befehl "strace" kann Systemaufrufe und -signale überwachen. Systemaufrufe umfassen auch das Lesen und Schreiben von Dateien.

$ sudo strace -t -p 3865
strace: Process 3865 attached
05:36:54 rt_sigsuspend([], 8)           = ? ERESTARTNOHAND (To be restarted if no handler)

Die Überwachung hat begonnen (Ende mit "Strg + C"). Lassen Sie in diesem Zustand nginx die Konfigurationsdatei lesen.

nginx lädt die Konfigurationsdatei neu, wenn es das HUP-Signal empfängt. Apache ist ein USR1-Signal, und andere Anwendungen können möglicherweise mit einem bestimmten Signal neu laden.

HUP changing configuration, keeping up with a changed time zone (only for FreeBSD and Linux), starting new worker processes with a new configuration, graceful shutdown of old worker processes

Controlling nginx

Sie können ein HUP-Signal mit einem lauten Befehl senden, der als "kill" -Befehl bezeichnet wird.

$ sudo kill -HUP 3865
05:37:25 --- SIGHUP {si_signo=SIGHUP, si_code=SI_USER, si_pid=53, si_uid=0} ---
05:37:25 rt_sigreturn({mask=[HUP INT QUIT USR1 USR2 ALRM TERM CHLD WINCH IO]}) = -1 EINTR (Interrupted system call)
05:37:25 stat("/etc/localtime", {st_mode=S_IFREG|0644, st_size=127, ...}) = 0
05:37:25 uname({sysname="Linux", nodename="1b01e2a57209", ...}) = 0
05:37:25 openat(AT_FDCWD, "/etc/nginx/nginx.conf", O_RDONLY) = 8
05:37:25 fstat(8, {st_mode=S_IFREG|0644, st_size=643, ...}) = 0

Es gab eine Bewegung in dem Terminal, das ich mit "strace" überwachte. Der Fokus liegt auf dem Systemaufruf "openat". Sie können sehen, dass Sie die Datei / etc / nginx / nginx.conf geöffnet haben.

Ich kenne den Speicherort der Konfigurationsdatei. Herzliche Glückwünsche!

Suchen Sie einen anderen Server

Es ist etwas ärgerlich, wenn das Problem wahrscheinlich auf einem anderen Server liegt. Sie können die Reverse-Proxy-Einstellungen von nginx überprüfen oder andere Server mithilfe der folgenden Methoden finden.

arp,arp-scan

Hosts im selben Subnetz können durch ARP-Scan gefunden werden, obwohl ich nicht ins Detail gehen werde. Wenn Ihnen der Inhalt des Caches nichts ausmacht, können Sie ihn auch mit dem Befehl arp überprüfen.

##Überprüfen Sie den Cache-Inhalt
$ arp -a
ip-172-31-16-1.ap-northeast-1.compute.internal (172.31.16.1) at 06:d0:4e:xx:xx:xx [ether] on eth0

##ARP-Scan (arp-Der Scan-Befehl muss separat installiert werden.
###Berechnen Sie den Bereich (Subzone) des ARP-Scans
$ ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.31.24.219  netmask 255.255.240.0  broadcast 172.31.31.255
###Subzone von oben(Netzwerkadresse/CIDR)Ist 172.31.16.0/20
$ sudo arp-scan 172.31.16.0/20
Interface: eth0, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.9.2 with 4096 hosts (http://www.nta-monitor.com/tools-resources/security-tools/arp-scan/)
172.31.16.1 06:d0:4e:xx:xx:xx (Unknown)
172.31.26.132 06:4e:7e:xx:xx:xx (Unknown)
172.31.29.38  06:8b:fe:xx:xx:xx (Unknown)

netstat,iptables(ip_conntrack),nftables(nf_conntrack)

Mit dem Befehl netstat können Sie sehen, welche TCP-Verbindungen und TCP / UDP-Ports empfangsbereit sind.

$ sudo netstat -anp
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      3214/sshd
tcp        0      0 172.31.24.219:22        xxx.xx.xxx.xxx:58168    ESTABLISHED 32051/sshd: USERNAME
tcp6       0      0 :::22                   :::*                    LISTEN      3214/sshd
tcp6       0      0 :::80                   :::*                    LISTEN      3003/docker-proxy

Dies ist das Ausführungsergebnis auf dem Server (außerhalb des Containers), auf dem nginx zuvor gestartet wurde. Ich spüre keine Anzeichen von Nginx, aber das ist normal. Dies liegt daran, dass die Kommunikation mit dem Docker-Container von iptables (nftables) NATed wird.

Wenn Sie sich beeilen und "netstat" im Container ausführen, erhalten Sie möglicherweise den Befehl "nicht gefunden". Aber beruhige dich. Lassen Sie uns von außerhalb des Containers überprüfen.

Sie können die NAT-Einstellungen mit dem Befehl iptables überprüfen.

$ sudo iptables -L
Chain FORWARD (policy DROP)
target     prot opt source               destination
DOCKER     all  --  anywhere             anywhere

Chain DOCKER (1 references)
target     prot opt source               destination
ACCEPT     tcp  --  anywhere             ip-172-17-0-2.ap-northeast-1.compute.internal  tcp dpt:http

Und von iptables / nftables NAT-fähige TCP-Verbindungen finden Sie in procfs von ip_conntrack oder nf_conntrack.

$ sudo cat /proc/net/nf_conntrack
ipv4     2 tcp      6 431997 ESTABLISHED src=xxx.xx.xxx.xxx dst=172.31.24.219 sport=57245 dport=80 src=172.17.0.2 dst=xxx.xx.xxx.xxx sport=80 dport=57245 [ASSURED] mark=0 zone=0 use=2
ipv4     2 tcp      6 103 TIME_WAIT src=172.17.0.2 dst=xx.xx.xx.xxx sport=46684 dport=8080 src=xx.xx.xx.xxx dst=172.31.24.219 sport=8080 dport=46684 [ASSURED] mark=0 zone=0 use=2

Die erste Zeile ist die Verbindung, über die der Zugriff auf den TCP 80-Port auf den Docker-Container NAT-verknüpft ist. Die zweite Zeile ist das NAT der Verbindung vom Docker-Container zum TCP 8080-Port auf dem externen Host.

Aus der zweiten Zeile können wir schließen, dass nginx möglicherweise einen umgekehrten Proxy für einen externen Host darstellt.

** Von einer Konsole wie AWS oder GCP ** (Load Balancer System)

Wenn das gefundene Kommunikationsziel ein Load Balancer ist, kann die Existenz des darüber hinausgehenden Servers nicht durchsucht werden. Leider habe ich keine andere Wahl, als mir die Einstellungen des Road Balancers anzusehen.

** Aus der Befehlshistorie aller **

Wenn Sie der Meinung sind, dass "jemand es tun muss", legen Sie einen Präzedenzfall fest. Der vom Befehl history ausgegebene Befehlsverlauf wird in .bash_history für bash gespeichert.

$ sudo cat /home/*/.bash_history | grep ssh
ssh -p 11122 example.com
ssh [email protected]

Schauen Sie sich den Server genauer an

Wenn Sie zu einem verdächtigen Server gelangen, überprüfen Sie ihn. Zusätzlich zu den bisher erläuterten Befehlen können auch die folgenden Befehle und Elemente verwendet werden.

procfs

Zusätzlich zu Dateideskriptoren und NAT-Sitzungen kann das proc-Dateisystem beim Start verschiedene Informationen wie Befehlszeichenfolgen einschließlich Parametern abrufen.

Zusätzlich zu procfs man page, linux procfs gründliche Einführung --SIer, aber ich möchte ein Technologie-Blog erstellen kann mit einem Ausgabebeispiel bestätigt werden.

/var/log/{syslog,messages}

Gesammelt von syslogd (rsyslogd) Es werden verschiedene Protokolle des geänderten Systems ausgegeben. Obwohl dies selten vorkommt, wird ein Datensatz aufgezeichnet, wenn OOM Killer für OOM Killer aktiviert wird (The OOM CTF). Und [Out of Memory Management](siehe https://www.kernel.org/doc/gorman/html/understand/understand016.html).

Dec 15 10:51:07 ip-172-31-24-219 kernel: Out of memory: Kill process 6359 (bash) score 635 or sacrifice child
Dec 15 10:51:07 ip-172-31-24-219 kernel: Killed process 6360 (yes) total-vm:114636kB, anon-rss:88kB, file-rss:0kB, shmem-rss:0kB
Dec 15 10:51:07 ip-172-31-24-219 kernel: oom_reaper: reaped process 6360 (yes), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

free,top,vmstat,ps

Obwohl es sich teilweise überlappt, ist es eine Hauptbefehlsgruppe, die Speicher, CPU, E / A und andere Informationen ausgibt. Ich werde es nicht erklären, aber es ist erwähnenswert, dass Sie LWP (Thread) auch mit ps -L anzeigen können.

## PID:Prozessnummer, LWP: LWP(Faden)ID, NLWP: LWP(Faden)Nummer
$ ps -efL
UID        PID  PPID   LWP  C NLWP STIME TTY          TIME CMD
root      3564     1  3564  0    8 02:24 ?        00:00:00 /usr/libexec/amazon-ecs-init start
root      3564     1  3567  0    8 02:24 ?        00:00:00 /usr/libexec/amazon-ecs-init start
root      3564     1  3568  0    8 02:24 ?        00:00:00 /usr/libexec/amazon-ecs-init start
(Kürzung)

Tor

Mit der bisher beschriebenen Methode können Sie jetzt Server, Anwendungen, Einstellungen und Protokolldateien finden und sehen, wie der Server aussieht.

Sie können auf Anfragen wie "Der Zugriff auf eine Webseite verursacht einen Fehler" antworten.

unicorn_err.log:E, [2019-12-15T21:18:43.339882 #10627] ERROR -- : worker=4 PID:14246 timeout (98s > 60s), killing
unicorn_err.log:E, [2019-12-15T21:18:43.339910 #10627] ERROR -- : worker=5 PID:14254 timeout (80s > 60s), killing

Wow, die Verarbeitung dauert mehr als 60 Sekunden! ??

(geht nicht weiter)

Zusammenfassung

Die diesmal verwendeten Befehle und Elemente lauten wie folgt.

Recommended Posts

Fehlerbehebungstechniken aus (fast) nichts
Keras aus dem Nichts
Keras ab dem 5. Platz
Keras ausgehend von nichts 1 ..
Keras ab nichts 4.
Keras ab nichts 2.
Keras ab dem 3. Platz