it-swarm.com.de

Missbrauch von cURL zur Kommunikation mit Redis

Ich möchte eine PING an Redis senden, um zu prüfen, ob die Verbindung funktioniert. Jetzt könnte ich einfach redis-cli installieren, aber ich möchte nicht, und curl ist bereits vorhanden. Wie kann ich also curl dafür missbrauchen? Grundsätzlich muss ich ausschalten, was hier gesendet wird:

> GET / HTTP/1.1
> User-Agent: curl/7.22.0 (x86_64-pc-linux-gnu) libcurl/7.22.0 OpenSSL/1.0.1 zlib/1.2.3.4 libidn/1.23 librtmp/2.3
> Host: localhost:6379
> Accept: */*
> 
-ERR wrong number of arguments for 'get' command
-ERR unknown command 'User-Agent:'
-ERR unknown command 'Host:'
-ERR unknown command 'Accept:'

Ich konnte den User-Agent durch das Hinzufügen von -A "" vollständig loswerden, aber für den Rest kann ich nichts anderes finden. Irgendeine Idee, wie ich das machen kann?

16
Mahoni

Wenn Sie curl verwenden möchten, benötigen Sie REST über RESP wie webdis, tinywebdis oder turbowebdis. Siehe https://github.com/markuman/tinywebdis#turbowebdis-tinywebdis--cherrywebdis

$ curl -w '\n' http://127.0.0.1:8888/ping
{"ping":"PONG"}

Ohne eine REST - Schnittstelle für Redis können Sie beispielsweise netcat verwenden.

$ (printf "PING\r\n";) | nc localhost 6379 
+PONG

Mit netcat müssen Sie das RESP-Protokoll selbst erstellen. Siehe http://redis.io/topics/protocol

update 2018-01-09

Ich habe eine leistungsfähige Bash-Funktion aufgebaut, die die Redis-Instanz zu jedem Preis über TCP pingt

    function redis-ping() {
            # ping a redis server at any cost
            redis-cli -h $1 ping 2>/dev/null || \
                    echo $((printf "PING\r\n";) | nc $1 6379 2>/dev/null || \
                    exec 3<>/dev/tcp/$1/6379 && echo -e "PING\r\n" >&3 && head -c 7 <&3)
    }

verwendung redis-ping localhost

29
Markus

Nicht curl, erfordert aber keine HTTP-Schnittstelle oder nc (ideal für Container, in denen nc nicht installiert ist).

exec 3<>/dev/tcp/127.0.0.1/6379 && echo -e "PING\r\n" >&3 && head -c 7 <&3

Sollte dir geben

+PONG

Sie können mehr darüber erfahren, was in diesem fantastischen Artikel passiert.

27
Joel B

Ich musste dem von @Markus bereitgestellten nc einen Schlaf hinzufügen, damit er von einem entfernten System aus funktioniert:

(printf "PING\r\n"; sleep 1) | nc remote.redis.hostname 6379

Siehe Request/Response-Protokolle und RTT: Redis Pipelining für Details.

14
Peter M

Wir erläutern die großartige Antwort von @Joel B. Ich brauchte dies in einem Shell-Skript im Docker-Container, ohne Curl, ohne redis-cli und nc ....__ Das REDIS, das ich teste, ist das öffentliche redis-ha-Helmdiagramm für kubernetes von hier: https : //github.com/helm/charts/tree/master/stable/redis-ha

Zu setzende Variablen sind:

  • REDIS_Host = Hostname (DNS-Adresse oder IP), der den Redis Master und den Sentinel .__ enthält. (Teilen Sie dies in separate Hosts auf, wenn diese getrennt sind, und ändern Sie die Ports Wenn Sie müssen - aber im Steuerdiagramm befinden sich Master/Slave und Sentinel im selben Pod und verwenden die Standardports.)

  • REDIS_STARTUP_TIMEOUT = Maximale Wartezeit bis zum Aufgeben - standardmäßig 10 Minuten

  • REDIS_STARTUP_RETRY = Sekunden zwischen den Tests warten - Standardeinstellung ist 15 Sekunden

  • DEBUG = setze dies auf "true", um die fehlgeschlagenen Antworten widerzuspiegeln

Die Feinheiten der Technik werden in den Kommentaren beschrieben (Ich empfehle Ihnen, die Kommentare beizubehalten, um Ihre Kollegen - und das zukünftige Selbst - vor dem Irrsinn zu bewahren, wenn Sie versuchen, die spitzen Klammern zu entziffern).

# wait for 10 mins and check again every 15 seconds
let n=${REDIS_STARTUP_TIMEOUT:-600}
let m=${REDIS_STARTUP_RETRY:-15}
ready=false
while ((n > 0)); do
    # These scripts are the best way to check if redis is running without having access to nc, curl or redis-cli
    # They write a "PING" to the redis and sentinel ports on the hostname "dc-ecm-redis-ha"
    # and look for a "PONG+" in return.
    #
    # Detailed explanation:
    # -  3<>/dev/tcp... opens a file handle identified as #3 for input and output on the tcp Host and port
    #    The Host $REDIS_Host is defined in DNS by the Kubernetes _service_, and the port is for redis or sentinel
    #    (Uses linux's low-level network-as-filesystem support. Think of it as a sort of poor-man's telnet)
    # -  "PING" followed by carriage-return is sent to the port by redirecting to the handle with >&3
    # -  The response from the port is sent to the head command with <&3
    # -  The first 5 bytes of the response are captured with -c 5. This removes the linebreak (\r) from the response
    # -  Standard Shell $() around the whole thing stores the result in a variable (master or sentinel)
    # -  When Redis is NOT ready, the result is generally a failure in the exec or some other error, which goes
    #    to stderr, so we wrap it in  { } > 2>&1 to capture that error in the variable too.
    # -  Success is measured by "+PONG" being in the variable
    # -  If you set the variable DEBUG to "true" (or "TRUE" -> the {,,} lower-cases it) the failed responses are echoed
    # -  (There are easier ways to do this if you have redis-cli installed or nc, but typically you don't on a docker container)
    # -  The whole thing waits n seconds for Redis to be ready, checking every m seconds
    #
    master=$( { exec 3<>/dev/tcp/${REDIS_Host}/6379 && echo -e "PING\r\n" >&3 && head -c 5 <&3; } 2>&1 )
    sentinel=$( { exec 3<>/dev/tcp/${REDIS_Host}/26379 && echo -e "PING\r\n" >&3 && head -c 5 <&3; } 2>&1 )
    if [ "$sentinel" = "+PONG" -a "$master" = "+PONG" ]; then ready=true;
       break;
   else echo "$(date) : Waiting $n more seconds for Redis master and sentinel to respond to PING"
        [[ "${DEBUG,,}" = "true" ]] && echo "master response was [$master]";
        [[ "${DEBUG,,}" = "true" ]] && echo "sentinel response was [$sentinel]";
        sleep $m
        ((n-=m))
    fi
done

if [ "$ready" = true ]
    then echo "$(date) : REDIS is ready"
    # do something when Redis is ready
else
    echo "$(date) : ERROR: REDIS is still not ready. Giving up waiting"
    # do something when Redis fails
fi
0
Rhubarb