Curl "Connection Refused" when connecting to server with external IP address
<p>I've created a RESTful server and I can successfully make requests and get responses when I use my local IP address.  I would like it to be exposed externally to the internet.  I set up a port forwarding rule but I cannot seem to get things working.  From what I'm reading the "Connection Refused" with (7) means something is blocking it whether it's a firewall or ISP issue.  Any ideas on what to do? </p>

<p>Here's my curl command that works with my local IP:</p>

<pre><code>Pako-2:Pokebot pako$ curl -X GET http://192.168.1.8:30000/api/v1/getrecord/test
{"data": [{"id": 1, "title": "learn python"}, {"id": 2, "title": "get paid"}]}
</code></pre>

<p>This is what I see when I try using my external IP address given to me by <a href="http://www.whatsmyip.org/" rel="nofollow">What's my ip</a></p>

<pre><code>Pako-2:Pokebot pako$ curl -X GET http://MyIpHere:30000/api/v1/getrecord/test
curl: (7) Failed to connect to myIPAddress port 30000: Connection refused
</code></pre>

<p>Here's the port forwarding rule I made in my router/modem
<a href="http://i.stack.imgur.com/GULGI.png" rel="nofollow"><img src="http://i.stack.imgur.com/GULGI.png" alt="enter image description here"></a></p>

<p>Here are my router/modem advanced settings options.  I tried tweaking my firewall settings, but no luck.  I tried with NAT only and also with Low Security Level with all ports checked.  </p>

<p><a href="http://i.stack.imgur.com/Cee9s.png" rel="nofollow"><img src="http://i.stack.imgur.com/Cee9s.png" alt="enter image description here"></a>
<a href="http://i.stack.imgur.com/qUZGL.png" rel="nofollow"><img src="http://i.stack.imgur.com/qUZGL.png" alt="enter image description here"></a>
<a href="http://i.stack.imgur.com/tVnpr.png" rel="nofollow"><img src="http://i.stack.imgur.com/tVnpr.png" alt="enter image description here"></a>
<a href="http://i.stack.imgur.com/ZMGhj.png" rel="nofollow"><img src="http://i.stack.imgur.com/ZMGhj.png" alt="enter image description here"></a></p>

<p>-----------------Edit-----------------</p>

<p>Here is the port forwarding screen, should I just set 30000 as the begin and end? 
<a href="http://i.stack.imgur.com/Rnp1U.png" rel="nofollow"><img src="http://i.stack.imgur.com/Rnp1U.png" alt="enter image description here"></a></p>

<p>Here is some python code for my server:</p>

<pre><code>from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
from SocketServer import ThreadingMixIn
import threading
import argparse
import re
import cgi
import json


TODOS = [
    {'id': 1, 'title': 'learn python'},
    {'id': 2, 'title': 'get paid'},
]

class LocalData(object):
    records = {}


class HTTPRequestHandler(BaseHTTPRequestHandler):
    print "HTTPRequestHandler BaseHTTPRequestHandler = ", BaseHTTPRequestHandler
    def do_POST(self):
        print "do_POST"
        if None != re.search('/api/v1/addrecord/*', self.path):
            ctype, pdict = cgi.parse_header(self.headers.getheader('content-type'))
            if ctype == 'application/json':
                length = int(self.headers.getheader('content-length'))
                data = cgi.parse_qs(self.rfile.read(length), keep_blank_values=1)
                recordID = self.path.split('/')[-1]
                LocalData.records[recordID] = data
                print "record %s is added successfully" % recordID
            else:
                data = {}
            self.send_response(200)
            self.end_headers()
        else:
            self.send_response(403)
            self.send_header('Content-Type', 'application/json')
            self.end_headers()
        return

    def do_GET(self):
        print "do_GET"
        self.send_response(200)
        self.end_headers()
        self.wfile.write(json.dumps({'data': TODOS}))
        return


class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
    allow_reuse_address = True

    def shutdown(self):
        self.socket.close()
        HTTPServer.shutdown(self)


class SimpleHttpServer():
    def __init__(self, ip, port):
        self.server = ThreadedHTTPServer((ip, port), HTTPRequestHandler)

    def start(self):
        self.server_thread = threading.Thread(target=self.server.serve_forever)
        self.server_thread.daemon = True
        self.server_thread.start()

    def waitForThread(self):
        self.server_thread.join()

    def addRecord(self, recordID, jsonEncodedRecord):
        LocalData.records[recordID] = jsonEncodedRecord

    def stop(self):
        self.server.shutdown()
        self.waitForThread()


if __name__ == '__main__':
    server = SimpleHttpServer("0.0.0.0", 30000)


    print 'HTTP Server Running...........'
    server.start()
    server.waitForThread()
</code></pre>

<p>------------------- Edit 2--------------------</p>

<p>Tried only having 1 port, not a begin/end range and it's expecting a range...
<a href="http://i.stack.imgur.com/dKiYN.png" rel="nofollow"><img src="http://i.stack.imgur.com/dKiYN.png" alt="enter image description here"></a>
<a href="http://i.stack.imgur.com/utpob.png" rel="nofollow"><img src="http://i.stack.imgur.com/utpob.png" alt="enter image description here"></a></p>

<p>I find it strange that you'd be getting connection refused from within the local network because the router should be able to detect that the external IP is a reference to itself. </p>

<p>That ability may depend on the router, but that's been my experience with networking. </p>

<p>That being said, if you'd like to test the external firewall after playing with the port forwarding rules, then you need a device not on the local network. </p>

<p>If another device like a smart phone with a cell plan isn't available to you, then you could try to use <a href="http://www.canyouseeme.org" rel="nofollow">CanYouSeeMe</a> to test if the port is being opened. </p>

<p>You may also want to set DHCP reservation for your server. In other words, set a static IP address. </p>

python curl networking portforwarding