Von Java auf passwortgeschützten Server zugreifen + Umgang mit Ports

setNewUser()

Mitglied
Hallo!
Ich bin ganz begeistert vom Forum. In wenigen Tagen habe ich so viel extrem gute Hilfe bekommen. Tausend Dank an der Stelle! Ich versuche mich, so gut ich kann zu revanchieren! 🙂

Noch zwei Fragen für heute:

1. Wie kann ein Client auf einen Server zugreifen, der Passwortgeschützt ist? Ein Client wird ja mit den Parametern Port und IP-Adresse generiert. Wo kann da ein Passwort hinzukommen?

(1b. Spielen hier eigentlich Accounts wie root und user eine Rolle?)

2. Mir ist auch noch nicht ganz klar, wie man mit den Ports umgehen sollte?
- Sollten (Müssen?) Server und Client u.U. denselben Port haben?
- Muss ich, wenn auf einem remote server mein Server-Programm läuft und ich lokal den Client-Anteil ausführen möchte, praktisch zwingend am Router eine zusätzliche Port-Freigabe einstellen? Das kommt mir nicht gerade wie das Gelbe vom Ei vor ... 😉

Vielen lieben Dank an alle Lesenden und Antwortenden!

LG
Chris
 
Wie kann ein Client auf einen Server zugreifen, der Passwortgeschützt ist? Ein Client wird ja mit den Parametern Port und IP-Adresse generiert. Wo kann da ein Passwort hinzukommen?
Du sprichst, wenn ich mich recht entsinne, von TCP-Verbindungen. Da gibt es kein Passwort, das ist Aufgabe des auf dieser Verbindung aufbauenden Protokolls. Was heißt, ein Client wird generiert?

Spielen hier eigentlich Accounts wie root und user eine Rolle?
Nein. Du hast anscheinend eine völlig falsche Vorstellung davon, wie das Netz funktioniert.

Ich versuche mal eine Beschreibung, ohne zu sehr in die technischen Details zu gehen. Die ist ggf. nicht ganz korrekt, sollte aber fürs Verständnis hilfreich sein:

Sollten (Müssen?) Server und Client u.U. denselben Port haben?
Nein. Stell Dir IP-Adresse und Port einfach wie Telefonanschluss und Durchwahlnummer vor. Wenn Du beim Finanzamt auf Durchwahl 321 anrufst, musst Du ja auch nicht von Nebenstelle 321 aus anrufen.

Muss ich, wenn auf einem remote server mein Server-Programm läuft und ich lokal den Client-Anteil ausführen möchte, praktisch zwingend am Router eine zusätzliche Port-Freigabe einstellen?
Nein. Der Router verbindet (wenigstens) zwei Netze - im privaten Bereich das private, lokale Netz mit dem öffentlichen Internet. Eine Netzwerkschnittstelle des Routers bekommt also eine Adresse aus dem privaten Netz (z. B. 192.168.0.1), eine andere Netzwerkschnittstelle des Routers eine Adresse, die in der Regel vom Provider zugewiesen wird (z. B. 178.27.13.1). Pakete, die ins Internet gehen, tragen als Absenderadresse diese öffentliche IP-Adresse. Wenn Du z. B. auf www.wieistmeineip.de gehst, wird Dir die Adresse angezeigt. Unabhängig davon, vom welchem Gerät im lokalen Netz aus Du es versuchst, wirst Du feststellen, dass immer die gleiche IP-Adresse angezeigt wird, nämlich die vom Provider zugewiesene IP-Adresse des Routers.

Dein Router ist also unter dieser IP-Adresse aus dem öffentlichen Netz erreichbar, nicht aber die Geräte auf der lokalen Seite ("hinter" dem Router), denn diese haben ja keine öffentliche IP-Adresse. Was man nun tun kann ist, eine Portfreigabe (Weiterleitung) einrichten und sagen: lieber Router, wenn Du ein Paket auf Port 80 empfängst, leite dieses bitte an den lokalen Rechner 192.168.0.22 weiter, damit dieser an Deiner Stelle das Paket verarbeiten kann. Wenn Du aber ein Paket auf Port 22 empfängst, leite dieses bitte an den Rechner 192.168.0.25 weiter. Ohne diese Freigaben ist kein Verbindungsaufbau von außen zu einem Rechner im lokalen Netz möglich. Daher ist ein Router automatisch auch eine Firewall.

Betreibst Du einen Server im Internet, dann bekommt der Server selbst eine öffentliche IP-Adresse, unter der er direkt erreichbar ist. Da gibt es keinen Router, den Du konfigurieren könntest.

Daher kannst Du vom lokalen Netz aus zu jedem Server, der im Internet betrieben wird, eine Verbindung aufbauen. Willst Du umgekehrt vom Internet aus auf einen lokalen Rechner hinter Deinem Router zugreifen, musst Du im Router eine Portfreigabe einrichten.
 
Du solltest Dich da wirklich etwas einlesen. Zumal Du einen Server gemietet hast. Für den bist Du verantwortlich.
 
Kannst du mir vielleicht spontan kurz ein paar sinnvolle Themen zum Einlesen sagen? 🙂 Bin lernwillig!


P.S.: Kann etwas passieren, wenn ich auf dem Server eine ServerKlasse laufen lasse, die clients accepted, und die Strings, die die localClients schreiben, diesen wiederholt?
🙂
 
An der Stelle - eher weniger.

Aber wenn du einen Server mietest, laufen da von vornerein Dienste und Co. Das heißt, du musst das Betriebssystem und was drauf installiert ist, aktuell halten. Denn sonst kann es dir passieren, dass im schlimmsten Fall irgendwann die Polizei bei dir steht, weil dein Server genutzt wurde Dinge zu verbreiten, die verboten sind. Das das passiert ist eher unwahrscheinlich, wahrscheinlicher ist, dass er gesperrt wird, bzw. entsprechende Kosten bei dir auflaufen weil zu viel Bandbreite verbraucht wurde.
 
Danke, ich werde das gleich durcharbeiten!




Letzte Frage für heute!
Ich habe jetzt einmal eine einfache Server- und eine einfache Client-Klasse geschrieben. Es ist so gedacht, dass die Server-Klasse auf einem remote Server läuft, der Client auf meinem eigenen PC.
Die Server-Klasse kriege ich zum Laufen, offenbar muss ich aber noch was am Client verändern, dass dieser sich verbindet. Wisst ihr, was?

LG



[CODE lang="java" title="Server (remote)"]
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;

public class MeinServer {
public static void main (String[] args) {
MeinServer server = new MeinServer(8000);
server.startListening();
}

private int port;

public MeinServer (int port) {
this.port = port;
}

public void startListening() {
new Thread(new Runnable() {
@Override
public void run() {
try {
System.out.println("[Server] Server starten...");
ServerSocket serverSocket = new ServerSocket(port);
System.out.println("[Server] Warten auf Verbindung..");
Socket remoteClient = serverSocket.accept();
System.out.println("[Server] Client verbunden: "
+ remoteClient.getRemoteSocketAddress());

Scanner s = new Scanner(new BufferedReader(
new InputStreamReader(remoteClient.getInputStream())));
if (s.hasNextLine()) {
System.out.println("[Server] Neue Nachricht vom Client: " + s.nextLine());
}

//Verbindungen schließen
s.close();
remoteClient.close();
serverSocket.close();

} catch (IOException e) {
e.printStackTrace();
}
}
}).run();
}
}
[/CODE]

[CODE lang="java" title="Client"]
import java.io.IOException;
import java.i😵utputStreamWriter;
import java.io.PrintWriter;
import java.net.InetSocketAddress;
import java.net.Socket;

public class MeinClient {

public static void main (String[] args) {
MeinClient client = new MeinClient("85.xxx.xx.xx6", 8000); // remote server
client.sendMessage("Guten Tag, Frau Server! Wie geht es Ihnen?");
}

private InetSocketAddress address;

public MeinClient (String hostname, int port) {
this.address = new InetSocketAddress(hostname, port);
}

public void sendMessage (String msg) {
try {
System.out.println("[Client] Verbinde zu Server...");
Socket socket = new Socket();
socket.connect(address, 5000);
System.out.println("[Client] Verbunden.");

System.out.println("[Client] Sende Nachricht...");
PrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()));
pw.println(msg);
pw.flush();
System.out.println("[Client] Nachricht gesendet.");

//Verbindung schließen
pw.close();
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
[/CODE]
 
P.S.: Kann etwas passieren, wenn ich auf dem Server eine ServerKlasse laufen lasse, die clients accepted, und die Strings, die die localClients schreiben, diesen wiederholt?
Die Wahrscheinlichkeit ist eher gering (vom Grundsatz her aber nicht ausgeschlossen). Es geht auch nicht darum, dass Du 100 %-ige Sicherheit herstellst, aber völlig ohne Sicherheitskonzept einen Server ins Netz zu stellen, ist grob fahrlässig.

Wenigstens ein paar Dinge solltest Du tun: Firewall einrichten und nur die Ports öffnen, die Du brauchst (22 für ssh-Zugriff und den Port für Deine Server-Annwendung), fail2ban installieren und sichere Passwörter verwenden. Natürlich sind die Systeme aktuell zu halten, d. h. insbesondere sicherheitsrelevante Updates einzuspielen.

Zusätzlich wäre zu empfehlen, den root-Login via ssh zu sperren (stattdessen verbindet man sich zuerst mit einem anderen User und switcht dann auf root) und passwortbasierten Login ganz abzuschalten (stattdessen authentifiziert man sich mit einem kryptografischen Schlüssel). Zudem kann man die kryptografischen Einstellungen von ssh noch verschärfen.
 
Die Server-Klasse kriege ich zum Laufen, offenbar muss ich aber noch was am Client verändern, dass dieser sich verbindet. Wisst ihr, was?
Geht es denn Lokal?
Sprich als IP nutzt du deine eigene (oder 127.0.0.1)?

Wie schon einmal geschrieben entwickelt und testet man erstmals Lokal. Dann stören keine fremden Netzwerke oder das Internet zwischen Server und Client.
 
Ich wollte eigentlich nur einmal kurz an einem Mini Beispiel sehen, wie das remote funktioniert. Als IP benutze ich die des remote servers (für einen Monat kostenlos zur Probe gemietet ^^). Ich möchte eben einmal kurz verstehen, was geändert werden MÜSSTE, damit das remote funktionieren würde 🙂
 
Die Server-Klasse kriege ich zum Laufen, offenbar muss ich aber noch was am Client verändern, dass dieser sich verbindet
Bekommst du im Client eine Exception? Schreibt der Server die Nachricht "[Server] Client verbunden:"?

Sobald der Client sich bei Server anmeldet, fragst du ab:
if (s.hasNextLine()) {
Ich vermute, dass zu diesem Zeitpunkt noch gar keine Nachricht des Clients beim Server angekommen ist.
Und sofort danach schließt du die Verbindung wieder.
Da hat der Cleint keine Chance, eine Nachricht zu schicken.
 
Auf welchem Port lauscht dein Server? Du connectest immer auf Port 5000, den Port den du in deinem Client übergibst, ist komplett irrelevant. Am sinnvollesten das ganze Adress Objekt wegzuwerfen und den Socket über new Socket(hostname, port) zu erzeugen.
 
Zuletzt bearbeitet:
Auf welchem Port lauscht dein Server? Du connectest immer auf Port 5000, den Port den du in deinem Client übergibst, ist komplett irrelevant. Am sinnvollesten das ganze Adress Objekt wegzuwerfen und den Socket über new Socket(hostname, port) zu erzeugen.
Nein, das connct wird für eine InetSocketAddress (die den Port enthält) aufgerufen, die 5000 ist der Timeout.
 
Die Server-Klasse kriege ich zum Laufen, offenbar muss ich aber noch was am Client verändern, dass dieser sich verbindet. Wisst ihr, was?
Das Beispiel funktioniert wunderbar. Du kannst mal den Server starten und Deinen Browser gen <server-ip>:8000 richten, dann solltest Du auf dem Server eine Ausgabe erhalten (z. B. Neue Nachricht vom Client: GET / HTTP/1.1). Wenn das funktioniert, sollte MeinClient auch funktionieren. Wenn Browser funktioniet, Dein Client nicht, könnte eine lokal installierte Software-Firewall schuld sein.
 
Das Beispiel funktioniert wunderbar.
Ich vermute einmal, dass du den Server auf "localhost" hast laufen lassen.
Das kann natürlich zu einem anderen Zeitverhalten führen. Meine Vermutung war ja, dass der Server noch keine Nachricht vom Client erhalten hat, wenn er nachfragt, ober bereits eine Nachricht erhalten hat (und sich dann beendet).

@setNewUser() : Du solltest dir darüber klar sei, dass Arbeiten mit TCP/IP anders funktioniert als der Aufruf einer Funktion (in Java). Die Antwort kommt später. Wichtiges Schlagwort ist in diesem Zusammenhang "asynchron" (bzw. "synchron").

Aber es ist eine Suche nach der Nadel im Heuhaufen, solange wir keine Antwort haben auf die Frage:
"Bekommst du im Client eine Exception? Schreibt der Server die Nachricht "[Server] Client verbunden:"?"
 
telnet sollte langsam genug gewesen sein 😉
Aber dennoch ist folgender Code doch verdächtig;
Java:
                    Socket remoteClient = serverSocket.accept();
                    Scanner s = new Scanner(new BufferedReader(
                            new InputStreamReader(remoteClient.getInputStream())));
                    if (s.hasNextLine()) {
                        System.out.println("[Server] Neue Nachricht vom Client: " + s.nextLine());
                    }
                    //Verbindungen schließen
                    s.close();
Wer garantiert denn, dass der Client schon eine Nachricht geschickt hat, bevor s.hasNextLine() aufgerufen wird.
Dass also zwischen serverSocket.accept() und s.hasNextLine() der Client arbeitet.
 
Ich wollte eigentlich nur einmal kurz an einem Mini Beispiel sehen, wie das remote funktioniert. Als IP benutze ich die des remote servers (für einen Monat kostenlos zur Probe gemietet ^^). Ich möchte eben einmal kurz verstehen, was geändert werden MÜSSTE, damit das remote funktionieren würde 🙂
Dazu musst du erst mal das Problem herausfinden.
Liegt es am Client, liegt es am Server, liegt es am Netzwerk dazwischen?

Daher nochmal: Teste das ganze auf einem Rechner (Client und Server auf einem Rechner laufen lassen). Wenn es da geht, liegt es am Netzwerk zwischen deinem Rechner und dem Miet-Server.
 
Hallo, danke für eure zahlreichen Antworten!

@ scanner: Ich habe ein Tutorial nachprogrammiert. Hier wurde schon auf die Fragwürdigkeit des "Scanners" hingewiesen, aber als Vereinfachung des Codes zu Lernzwecken gerechtfertigt

@Offline-Testen:
Ja, das habe ich gemacht (an ein und demselben Gerät mit "localhost"), was funktioniert hat. Jetzt will ich eben rausfinden, was ich ändern muss, damit es remote (zum Server außerhalb meines WLans) funktioniert. Das einzige, was ich bislang geändert habe, war die IP (von "localhost" zur IP des Mietservers) - ohne genau zu wissen, ob man sonst noch etwas anpassen muss (Ports...).

@Fehlermeldung:
Es meckert lediglich der (lokal laufende) Client:


"/Applications/IntelliJ IDEA CE.app/Contents/jbr/Contents/Home/bin/java" -javaagent:/Applications/IntelliJ IDEA CE.app/Contents/lib/idea_rt.jar=57079:/Applications/IntelliJ IDEA CE.app/Contents/bin -Dfile.encoding=UTF-8 -classpath /Users/xxx/ServerCientFebruar21/out/production/ServerCientFebruar21 com.xxx.client.MeinClient

Verbinde zu Server...

java.net.SocketTimeoutException: connect timed out
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:609)
at com.xxx.client.MeinClient.sendMessage(MeinClient.java:28)
at com.xxx.client.MeinClient.main(MeinClient.java:14)
[Client] Verbinde zu Server...
java.net.SocketTimeoutException: connect timed out
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:609)
at com.xxx.client.MeinClient.sendMessage(MeinClient.java:28)
at com.xxx.client.MeinClient.main(MeinClient.java:14)
[Client] Verbinde zu Server...
java.net.SocketTimeoutException: connect timed out
at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
at java.base/java.net.Socket.connect(Socket.java:609)
at com.xxx.client.MeinClient.sendMessage(MeinClient.java:28)
at com.xxx.client.MeinClient.main(MeinClient.java:14)


Der remote-Server (angewählt im MacOS-Terminal) gibt aus:
Java:
[Server] Server starten...
[Server] Warten auf Verbindung..

@Browser gen Server richten
Ich habe die empfohlene Zeil (<IP des Mietservers>:8000) einfach mal im Safari in die URL-Leiste getippt, was zu folgender Meldung führte:
Code:
Safari kann keine Verbindung zum Server aufbauen              
Safari kann die Seite "85.xxx.xx.xx6:8000" nicht öffnen,
da Safari keine Verbindung zum Serever "85.xxx.xx.xx6" aufbauen kann.

Danke euch, ich bin sehr gespannt!
LG Chris
 
Zuletzt bearbeitet:
Fehler gemacht! Ich hatte im Client bei der Server-IP einen Zahlendreher.
Der Server reagiert trotzdem nicht und der Client meldet, dass er offenbar zurückgewiesen wurde:

Code:
[Client] Verbinde zu Server...
java.net.ConnectException: Connection refused (Connection refused)
    at java.base/java.net.PlainSocketImpl.socketConnect(Native Method)
    at java.base/java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:399)
    at java.base/java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:242)
    at java.base/java.net.AbstractPlainSocketImpl.connect(AbstractPlainSocketImpl.java:224)
    at java.base/java.net.SocksSocketImpl.connect(SocksSocketImpl.java:403)
    at java.base/java.net.Socket.connect(Socket.java:609)
    at com.xxx.client.MeinClient.sendMessage(MeinClient.java:28)
    at com.xxx.client.MeinClient.main(MeinClient.java:14)
 
🙂 🙂 🙂

Ha! Es hat doch funktioniert:

Server:
Code:
[Server] Server starten...
[Server] Warten auf Verbindung..
[Server] Client verbunden: /80.xxx.xxx.xx:xxxx9
[Server] Neue Nachricht vom Client: Guten Tag, Frau Server! Wie geht es Ihnen?

Problem war offenbar zuletzt, dass sich das Server-Programm bereits verabschiedet hatte (ohne in dies im Terminal anzuzeigen).

Was muss man eigentlich machen, wenn man in der SSH/Terminal ein Programm starten will, dass "ewig" und evtl. auch im Hintergrund laufen soll?

Auf jeden Fall: Tausend Dank für die große Hilfe bei dieser schweren Geburt!
🙂 🙂 🙂
 
Allerdings kommt die Hin-und-her-Kommunikation, die lokal funktioniert hat, hier nicht zustande ...

80.xxx.xxx.xx:xxxx9

Ist das am Ende ein Port? Der sieht wieder ganz anders aus ... 😉
 
Hier ein paar Artikel dazu:



Hi, hab deine Artikel gelesen. Sehr spannend und hilfreich! 🙂 Hab erst letztens dazu einen super spannenden Film gesehen. Meiner Meinung nach echt sehenswert! Geht auch um Hacker und generell das Thema hacking. Nur empfehlenswert 🙂

Hier könnt ihr ihn euch ansehen!

LG!
 

Zurück
Oben