Avatar billede jesperhw Nybegynder
12. juni 2003 - 13:14 Der er 45 kommentarer

Kan ikke åbne RMI port

I et Java program har jeg en RMI server kørende, som det er meningen at man kan kalde op fra Internettet. Men jeg kan ikke få konfigureret min router til at åbne op for serverens port.

I programmet har jeg sat serveren til at lytte på port 8090 men kan altså ikke åbne denne port for Internet-kommunikation.

Min router er en Cisco 677 med direkte forbindelse til pc'en (jeg har intet LAN). Mit OS er Win XP Pro.

Jeg har - uden held - prøvet følgende kommando til routeren for at åbne porten (via Hyperterminal):

"set nat entry add 192.168.1.4 8090 <min eksterne IP her> 8090 tcp"

Addressen 192.168.1.4 er min localhost (pc'ens interne IP). Nogen forslag?
Avatar billede arne_v Ekspert
12. juni 2003 - 14:58 #1
Er du oprmæeksom på at en RMI client skal brueg 2 porte:
  - en port til RMIRegistry
  - en port til server-applikationen
?
Avatar billede jesperhw Nybegynder
12. juni 2003 - 22:21 #2
Jeg tror ikke det er problemet, for programmet (dvs. serveren) har kunne køre hos en kammerat, og jeg har været i stand til at kalde serveren der kører hos ham (hans forbindelse er med ADSL-modem og ikke router).

Jeg havde opfattelse af at det var nok at give RMIregistry en port, og registrere sin(e) server(e) der vha. et navn (Naming). Så kan en klient kalde "lookup" på den IP hvor rmiregistry findes + et navn for det objekt (dvs. serveren) som skal kaldes op. Men RMIregistry tildeler måske mit server-objekt en port at lytte på bag kulissen?

Her er koden der bruges til at oprette enten en klient eller en server (serveren oprettes i "else" statementet). Koden er fra en GUI hvor brugeren bestemmer om han vil være klient eller server:

    try
        {
            JButton source = (JButton)e.getSource();
            if (source.getText().equals("Log på"))
            {
                //Der forsøges at logge på serveren her, og venter så.
                SpeedCarRemoteImpl remoteplayer = new SpeedCarRemoteImpl(navn.getText());
                SpeedCarServer scs = (SpeedCarServer)Naming.lookup("rmi://"+ip.getText()+":8090/speedcar");
                remoteplayer.setServerObj(scs);
                scs.tilfoejSpiller(remoteplayer);
                this.dispose();
            }
            else if (source.getText().equals("Jeg initierer spillet"))
            {
                //Serveren oprettes her hvis denne knap er valgt
                SpeedCarServerImpl scs = new SpeedCarServerImpl(navn.getText());
                java.rmi.registry.LocateRegistry.createRegistry(8090);
                Naming.rebind("//localhost:8090/speedcar", scs);
                new ServerGUI(scs);
                this.dispose();
            }
       
        }
Avatar billede arne_v Ekspert
12. juni 2003 - 22:24 #3
Ovenstående får rmiregirstry til at lytte på port 8090
og client connecter til den, får en stub som så connecter til en
server port.
Avatar billede arne_v Ekspert
12. juni 2003 - 22:25 #4
Så hvis serveren kører bag en router med NAT skal der være åbnet
for 2 porte (og man skal gøre lidt for at bestemme hvilken port
serveren skal lytte på).
Avatar billede fredslund Nybegynder
14. juni 2003 - 00:13 #5
arne_v - kan du forklare hvad (eller hvordan) det præcist skal gøres, - jeg har nemlig præcist det samme problem som jesperhw.... - og jeg kan ikke finde ud af at "tvinge" kommunikationen igennem en bestemt port!!
Avatar billede arne_v Ekspert
14. juni 2003 - 10:37 #6
Avatar billede arne_v Ekspert
14. juni 2003 - 10:40 #7
Den forklarer både hvad der sker og hvordan man løser problemet med en socket
factory.
Avatar billede arne_v Ekspert
24. juni 2003 - 20:53 #8
jesper>

Kunne du bruge svaret ?
Avatar billede jesperhw Nybegynder
25. juni 2003 - 21:25 #9
arne>

Undskyld jeg ikke har givet lyd fra mig før nu - har haft andet at lave...

Jeg har lige prøvet det eksempel af som ligger sammen med nævnte artikel (indeholder en server + client). Inden jeg prøvede eksemplet var jeg inde og åbne ALLE porte i routeren (forhåbentlig), så det burde være lige meget hvilke porte der blev lyttet på. Men efter at have startet serveren og derefter klienten kører de begge et par sekunder og så spytter klient-konsollen følgende fejl ud:

java.rmi.ConnectException: Connection refused to host: 192.168.1.3; nested excep
tion is:
        java.net.ConnectException: Connection refused: connect
        at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:567)
        at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185
)
        at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
        at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:101)
        at ServerImpl_Stub.toUpperCase(Unknown Source)
        at Client.run(Client.java:29)
        at java.lang.Thread.run(Thread.java:536)
Caused by: java.net.ConnectException: Connection refused: connect

..osv.

Klienten kan altså ikke connecte til 192.168.1.3 som er pc'ens interne ip. Det tyder altså på at jeg ikke har fået åbnet for alle porte alligevel. Nu ved jeg ikke hvor meget du kender til Cisco 677 routeren fra Tiscali, men jeg brugte denne kommando i Hyperterminal:

set nat entry add 192.168.1.3 1025-65535 <min faste IP her> 1025-65535 tcp

og en tilsvarende for udp.

Ved du om det er nok til at åbne alle portene fra 1025 og op?
Avatar billede arne_v Ekspert
25. juni 2003 - 21:39 #10
RMI bruger kun TCP ikke UDP.

Og jeg tror at du skal:

1)  lave Java kode så den bruger 2 kendte porte - lad os kalde dem X og Y

2)  åbne for port X og Y i routeren

3)  forwarde fra routerens eksterne IP adress port og X og Y til
    serverens interne IP port X og Y

så burde det faktisk virke.

Hvilke 2 porte har du bedt den bruge ?
Avatar billede jesperhw Nybegynder
25. juni 2003 - 22:11 #11
Rmiregistry ligger på 1099.
Den hjemmelavede socket factory sætter ServerSocket for server-objektet til 1098.

Har nu åbnet for disse 2 porte.
Men såvidt jeg kan se prøver den kaldende klient også at bruge port 1098? I hvert fald får den ikke lov at connecte - jeg får samme række exceptions som før.
Avatar billede arne_v Ekspert
25. juni 2003 - 22:15 #12
Kan du ikke prøve at teste med noget simplere.

Et lille server program som laver en ServerSocket på 1098.

Og så enten et lille client program der connecter til 1098 eller
bare bruge en god gammeldags telnet til at connecte til port 1098
udefra.

Hvis det ikke virker, så er det et Cisco 677 problem.

Hvsi det virker så er et RMI kode problem.
Avatar billede arne_v Ekspert
11. juli 2003 - 19:09 #13
jesper>

Er du kommet videre ?
Avatar billede arne_v Ekspert
22. juli 2003 - 22:45 #14
??
Avatar billede arne_v Ekspert
27. august 2003 - 23:57 #15
??
Avatar billede fredslund Nybegynder
01. september 2003 - 20:41 #16
arne_v>

Jeg har nu også prøvet eksemplet nogle gange, og får præcis samme exception som Jesper - uanset hvilken computer(og router) jeg lader være server/klient.

Men Telnet virker??
Avatar billede arne_v Ekspert
01. september 2003 - 21:01 #17
Du har lavet en kombineret server og rmiregistry med en socket factory som returnerer 1098 og 1099, du har åbnet for port 1098 og 1099 i routeren,
og du kan ikke connecte ?
Avatar billede fredslund Nybegynder
03. september 2003 - 22:14 #18
Ja, ja, ja - og nej!
Det kan lyde underligt, - men det er altså faktum, og hvis det "ikke kan lade sig gøre", så tror jeg kun det kan være de routere, som jeg har prøvet eksemplet med, der kan være årsag til problemet. Det virker fint når jeg bare kører lokalt, - men ikke når jeg bruger maskiner, der ikke er på samme netværk. Har du prøvet det i praksis arne_v?
Avatar billede arne_v Ekspert
03. september 2003 - 22:29 #19
Nej aldrig.

Efter min bedste overbevisnig er RMI en LAN teknologi.

Til en WAN løsning ville jeg vælge SOAP over HTTP (web service).

Jeg tror stadig at det kan lade sig gøre, men jeg har meget svært ved
at forstå præcis hvad I gør.

Men hvis det er interessant kan jeg da prøve at lave et setup med
RMI server inden for min router og en RMI client udenfor.
Avatar billede fredslund Nybegynder
03. september 2003 - 22:36 #20
Jeg tror du har ret i, at det ikke er specielt smart som WAN-løsning.. - men jeg er i en situation, hvor det vil være rart at være på den sikre side.. - altså at få det til at virke alligevel.

Det ku' da være sjovt at se, om du kan få det til at virke.. - evt. med det eksempel, som du selv har linket til! - Det ser i hvert fald ud som om, at dette eksempel kan tvinge igennem på en bestemt port - så mangler vi bare at komme igennem denne port :-)
Avatar billede arne_v Ekspert
03. september 2003 - 22:40 #21
OK.

Jeg prøver - imorgen eller fredag aften.
Avatar billede fredslund Nybegynder
03. september 2003 - 22:41 #22
Spændende.. - og på forhånd tak!
Avatar billede arne_v Ekspert
06. september 2003 - 12:41 #23
Jeg fik det til at virke.
Avatar billede arne_v Ekspert
06. september 2003 - 12:42 #24
import java.io.IOException;
import java.net.MalformedURLException;
import java.rmi.Naming;
import java.rmi.RMISecurityManager;
import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.rmi.server.RMISocketFactory;
import java.rmi.registry.LocateRegistry;

public class TestImpl extends UnicastRemoteObject implements Test {
  public TestImpl() throws RemoteException {
      super();
  }
  public String dup(String s) {
      return (s + s);
  }
  public static void main(String[] args) {
      try {
        System.setSecurityManager(new RMISecurityManager());
        RMISocketFactory.setSocketFactory(new FixedPortRMISocketFactory());
        LocateRegistry.createRegistry(60000);
        Naming.rebind("rmi://" + args[0] + ":60000/dup", new TestImpl());
      } catch (RemoteException e) {
        e.printStackTrace();
      } catch (MalformedURLException e) {
        e.printStackTrace();
      } catch (IOException e) {
        e.printStackTrace();
      }
  }
}
Avatar billede arne_v Ekspert
06. september 2003 - 12:42 #25
import java.io.IOException;
import java.net.Socket;
import java.net.ServerSocket;
import java.rmi.server.RMISocketFactory;

public class FixedPortRMISocketFactory extends RMISocketFactory {
  private static int socketNumber = 60001;
  public Socket createSocket(String host, int port) throws IOException {
      System.out.println("client socket " + host + ":" + port);
      return new Socket(host, port);
  }
  public ServerSocket createServerSocket(int port) throws IOException {
      System.out.println("server socket " + port);
      if(port == 0) {
          port = socketNumber;
          System.out.println("server socket " + port);
          socketNumber++;
      }
      return new ServerSocket(port);
  }
}
Avatar billede arne_v Ekspert
06. september 2003 - 12:42 #26
Åbne for TCP port 60000 og 60001 i router.
Avatar billede arne_v Ekspert
06. september 2003 - 12:43 #27
-Djava.rmi.server.hostname=min-eksterne-IP på start af server.
Avatar billede arne_v Ekspert
06. september 2003 - 12:43 #28
stub uploadet manuelt til client.
Avatar billede fredslund Nybegynder
08. september 2003 - 18:27 #29
Det ser ud til, at du har fat i noget..! - Jeg har dog ikke fået det til at virke enenu, men nu får jeg en AccessControlException.

Måske er det noget der kan løses via java.policy eller java.security i C:\j2sdk1.4.1_02\jre\lib\security - eller hva'? - Har du gjort noget ved disse filer?
Avatar billede arne_v Ekspert
08. september 2003 - 18:32 #30
Ja.

Jeg kørte med all granted.

Det skal I naturligvis ikke i produktion.

Så skal I have lavet en permission til lige præcis det nødvendige.
Avatar billede fredslund Nybegynder
16. september 2003 - 09:26 #31
Utroligt - men desværre; jeg kan stadig ikke få det til at virke. Jeg er kommet ud over problemet med AccessControlException, - jeg kører med all granted, men får stadig en ConnectException??

Det virker stadig, hvis jeg forsøger fra min egen pc via min eksterne IP, men ikke når jeg forsøger med to computere over internettet? Den finder rigtigt nok ud af hvilken IP min server har indenfor routeren, men får altså ikke adgang af en eller anden årsag... - Har du gjort andre sikkerhedsmæssige tiltag end all granted i java.policy?
Avatar billede arne_v Ekspert
16. september 2003 - 10:19 #32
Har du all granted i "begge ender" ?
Avatar billede fredslund Nybegynder
16. september 2003 - 12:28 #33
Ja
Avatar billede arne_v Ekspert
16. september 2003 - 12:36 #34
Hvordan pokker kan man få en AccessControlException med all granted ?

Det lyder skummelt.

Kan du poste hele fejlen ?
Avatar billede fredslund Nybegynder
03. december 2003 - 19:28 #35
Hej arne_v!

Så er jeg - efter nogen tid med andre gøremål - tilbage ved et snart gammelt problem, som jeg stadig ikke er i stand til at løse! - Nedenfor har jeg bragt en udskrift af fejlen. I eksemplet har jeg forsøgt at tilgå en simpel server med metoden sigHej() - placeret på en kammerats computer med all granted i begge ender og ved brug af den factory, som du tidligere har posted. IP'en 10.0.0.4 er adressen bag routeren, så den bliver dirrigeret det rigtige sted hen, men ender altså med time-out...

Håber du kan hjælpe!


java.rmi.ConnectException: Connection refused to host: 10.0.0.4; nested exception is:
java.net.ConnectException: Connection timed out: connect
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:567)
at sun.rmi.transport.tcp.TCPChannel.createConnection(TCPChannel.java:185)
at sun.rmi.transport.tcp.TCPChannel.newConnection(TCPChannel.java:171)
at sun.rmi.server.UnicastRef.invoke(UnicastRef.java:101)
at Server_Stub.sigHej(Unknown Source)
at Klient.test(Klient.java:21)
at Klient.main(Klient.java:38)

Caused by: java.net.ConnectException: Connection timed out: connect
at java.net.PlainSocketImpl.socketConnect(Native Method)
at java.net.PlainSocketImpl.doConnect(PlainSocketImpl.java:305)
at java.net.PlainSocketImpl.connectToAddress(PlainSocketImpl.java:171)
at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:158)
at java.net.Socket.connect(Socket.java:426)
at java.net.Socket.connect(Socket.java:376)
at java.net.Socket.<init>(Socket.java:291)
at java.net.Socket.<init>(Socket.java:119)
at sun.rmi.transport.proxy.RMIDirectSocketFactory.createSocket(RMIDirectSocketFactory.java:22)
at sun.rmi.transport.proxy.RMIMasterSocketFactory.createSocket(RMIMasterSocketFactory.java:128)
at sun.rmi.transport.tcp.TCPEndpoint.newSocket(TCPEndpoint.java:562)
... 6 more
Avatar billede arne_v Ekspert
03. december 2003 - 20:03 #36
Og der er lukket op for den port ?
Avatar billede fredslund Nybegynder
03. december 2003 - 20:10 #37
Ja, - der er åbnet for port 1099 samt den valgte port (i dette tilfælde 1098) på serveren...
Avatar billede rohde Nybegynder
04. januar 2005 - 13:10 #38
Hej
Blev der nogen løsning på dette problem da jeg nu sidder men en Cisco router 2600XM der giver samme symtomer som ovenstående. Har alle porte åbne og anvender 80 1099 1098.
Alt virker fint når jeg ikke anvender router men får security problemer når router komme imellem.
Avatar billede arne_v Ekspert
04. januar 2005 - 13:23 #39
Mit gæt vil være at serveren skal startes med:

-Djava.rmi.server.hostname=xxx.domain.dk

således at serveren der kører på indvendig side af firewallen kan
fortælle den rigtige adresse til client  (som jo skal connecte til
den eksterne adresse)
Avatar billede arne_v Ekspert
04. januar 2005 - 13:24 #40
Avatar billede rohde Nybegynder
04. januar 2005 - 13:39 #41
Tak for svaret jeg kigger lidt paa det.
Avatar billede rohde Nybegynder
04. januar 2005 - 19:36 #42
Fejlen er fundet. Routeren har et java filter. Jeg sender nogle flere oplysninger senere.
Avatar billede rohde Nybegynder
05. januar 2005 - 13:40 #43
I routeren bliver en regel navngivet, og reglen tilføjet på interfacet.

ip inspect name fw tcp
ip inspect name fw udp
ip inspect name fw http
...osv...

interface fastethernet 0/0.1
ip inspect fw in

I ovenstående er det keywordet http der enabler java-blocking.
Bemærk at hver enkelt kommando enabler inspicering af en protokol type.

Har fjernet denne kommando fra begge LIS routere. (http kommandoen altså


NB : Cisco syntaxen er en smule fjollet, den burde retteligt have heddet :
ip inspect name fw java (el. lign.)

NB : Bemærk at man kan have flere forskellige navngivne regler, og derrmed forskellige niveauer af inspicering på forskellige interfaces.

NB : Bemærk også, at Java applets enten bliver blokket fra samtlige sites eller ingen (igen lidt tamt fra Ciscos side :)
Avatar billede arne_v Ekspert
05. januar 2005 - 22:01 #44
Nu er en java socket connection ikke på nogen måde anderledes end
en C socket connection. En firewall kan ikke identificere programmerings
sproget.

Mit gæt er at den kommando får firewall'en til at rejecte alt som
ikke er valide HTTP requests. Og det er en RMI connection naturligvis ikke.
Avatar billede rohde Nybegynder
06. januar 2005 - 11:38 #45
Ovenstående forklaring kommer fra dem der har sat routeren op. Jeg skriver mig dette bag øret og takker for svaret. :-)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester