Accessing locally hosted site through public ip - python

I have setup a django app on a apache server in a VM. The site is accessible when I use the apache server IP in the VM browser. It is also accessible from the host browser through it's local IP. But, I cannot access it through the public IP over the internet. I get a site can't be reached error
I have set up port forwarding such that:
1. All router requests on port 80 are forwarded to local IP
2. All requests to local IP on port 80 are forwarded to the VM
I checked if my port is open on my public ip using http://www.yougetsignal.com/tools/open-ports/
It says that my port is closed. Same results with http://canyouseeme.org/
I am able to ping my public ip successfully.
I have tried disabling all my firewalls but this has not helped. Please tell me if you need any code to be shared. Any help would be appreciated.
Edit:
Extra information: It seems my router's WAN IP is different from my public IP. I can access the site through the WAN IP from the host browser but again, I am not able to access it over the internet.

You just need a public IP address or push your application to the hosting (like this for example https://gpdhost.com/offers/).
ToDo: learn DMZ, learn WAN-LAN packet forwarding process, learn TCP/IP routing, learn public and private IP addressing and learn NAT.
Description: http/https connection conversation (client-outside vs your-server):
1) client: in browser write: sharan-site/;
2) get IP by DNS name from public servers? But public servers don't know your ip:dns-name pair...
=> fail
next example:
1) client: 192.168.1.1/ - where IP is your server
2) so where is it?
=> nowhere, it is private IP address! Fail...
Desc+: Port forwarding it is NAT feature. Your router must have public IP address, and you must setup DMZ like scheme in your local network: https://www.cisco.com/c/en/us/support/docs/ip/network-address-translation-nat/13772-12.html
Desc++: that sites check outside tcp/80 port on your router and PC, and it's open, no questions... But this no help for your task.

Related

How to connect client in a internet to the server

I made a simple chat room. But I can't connect clients who joined through internet. I know I'm using local network to this program. But I researched how to connect my server to the internet. I used my Dynamic public IP and port forwarded using my router, but It didn't work. And I used ngrok, but it also didn't work. How can I solve this problem.
This is a part of my program.
IP_Address = 'IP'
Address = (IP_Address,PORT)
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind(Address) # Bind IP address and Port to this socket.
When I used my public addressit shows this error.
Traceback (most recent call last):
File "Documents/Projects/Python/server.py", line 13, in <module>
server.bind(Address) # Bind IP address and Port to this socket.
OSError: [Errno 99] Cannot assign requested address
Use server.bind(('',port)) or server.bind(('0.0.0.0',port)). Both mean "bind to all interfaces".
If you want to bind to a specific interface, use your local IP, not the public one. Use ipconfig from the console to see your IP address.
On the router, forward the port to your local IP. Clients on the internet connect to your public IP and port.
I think the best way to solve this problem is using a Cloud Application Platform to run the server program.

Google DNS Server

I wanted to get my private IP address using Python, so I found a snippet of code that does it.
import socket
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
print(s.getsockname()[0])
s.close()
Here 8.8.8.8 is address for Google DNS server. Now whenever we hit an external site, we are only represented by our public IP address, so how is Google DNS able to find my Private IP address ? Moreover this was working even when my Internet connection was off.
I wanted to get my private IP address using Python, so I found a snippet of code that does it. ... so how is Google DNS able to find my Private IP address ?
This snippet of code does not do what you expect it to do. All it reports is the local IP address from an UDP socket "connecting" to 8.8.8.8. This information does not come from Google, it comes from your local operating system which of course knows what its local IP address is. In fact, you could connect to any other external IP address and you'll get the same information back.
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.connect(("8.8.8.8", 80))
Apart from that the code is wrong too. It does not connect to the DNS server - the DNS server would be port 53 and not port 80 as you use here.

Apache runs wsgi module (django application) twice in case of public router ip and internal server ip?

We've below netwrok setup
Internal server ip : 192.168.153.20:443
Public router ip : 111.93.87.11:26060
We've port forwarding in router : 111.93.87.11:26060 to 192.168.153.20:443
So when we first access 192.168.153.20:443(Internal server ip) it runs/execute django application ( First time )
Now when we access 111.93.87.11:26060 (Public router ip) - due to port forwarding it comes to internal server ip but as apache receives host:111.93.87.11:26060,apache execute/run whole django application second time.
So ulimately our application is being run two times for ip i.e internal ip and public router ip.
This is creating very critical issue.
This is may be due to Apache configuration.
We need to run single instance for both internal and external IP. But it seems Apache parsing host name and running different instance for new external IP
For reference
Apache configuration attached in image
Actually we've to add/provide Public IP in server name as when any request comes it checks and matches with server name if is found then it will execute the same and to pass a request we've to use ProxyPass
Final public router ip working with SSL
Added below lines in httpd-ssl.conf file
ServerName 111.93.87.11
SSLEngine on
SSLProxyEngine on
SSLCertificateFile "/usr/local/vcs/cert/certs/DefaultServerCert_VCS.pem"
SSLCertificateKeyFile "/usr/local/vcs/cert/certs/key/DefaultServerCert_VCS.key"
ProxyPass "/" "https://192.168.153.120:443/"

Accessing device on local network through server hosted webhook

I have a python script that acts as a webhook. A part of it is as follows:
import json
import os
import urllib
import socket
import _thread
from flask import Flask
from flask import request
from flask import make_response
app=Flask(__name__)
ip = ('192.168.1.75', 9050)
#app.route('/webhook',methods=['GET','POST'])
def webhook():
_thread.start_new_thread(sendDataToDevice,(ip))
req = request.get_json(silent=True,force=True)
print("Request:")
print(json.dumps(req,indent=4))
res=makeWebHookResult(req)
res=json.dumps(res,indent=4)
r=make_response(res)
r.headers['Content-Type']='application/json'
return r
if __name__ == '__main__':
app.run(port=8080,host='localhost')
The function of the script is to send some data to a device connected to the local network.
It works flawlessly when I open my web browser and type the following on the url bar:
http://localhost:8080/webhook
I want to host the script on a server, eg. Heroku. How can I access the local device in that case?
Note: I know I can run the script on my local machine and make it visible to the internet using ngrok, but I want to keep it accessible even when my computer is switched off. Also, want a fixed link, and the links given by ngrok change on every run.
I've faced a similar issue before with IoT. Unfortunately there is no simple way to make a device be visible online. Here's a simple solution I've used. It might not be the best, but it works.
DDNS + Port Forwarding + Static IP
If you have access to your local WiFi router, then you can setup something called as DDNS (Dynamic Domain Name System). Your router will then connect to a DDNS service provider like no-ip (www.noip.com) and it will be visible on the internet. You can give a custom URL like susmit-home.noip.com.
However susmit-home.noip.com will now point only to your WiFi router and not your WiFi network. So if you want to access the local device_ip and device_port such as "192.168.1.75", 9050. Then you can setup Port Forwarding on your router for that local IP-Port combination. Usually the setup looks like this:
Local IP: device_ip (e.g. 192.168.1.75)
Local Port: device_port (e.g. 9050)
Outbound Port: any_port (e.g. 9050)
Make sure that your device_ip is a static IP on your WiFi router so that it doesn't change.
Finally in your code you can just replace the line ip = ('192.168.1.75', 9050) with ip = ('susmit-home.noip.com', 9050).
Other solutions:
A slightly more complicated solution is setting up a VPN, such that your local network and your remote server (e.g. Heroku) will all be available to each other as if they were within the same local network.
If your device is a computer or a Raspberry Pi, then you can use SSH Remote Port Forwarding to have access to your local device from the remote server.

Flask server not visible from my public ip address

I'm trying to run a flask server on my desktop PC that is publicly available on the internet. I've done the following:
Set up a static IP address: 192.168.1.11 (http://i.imgur.com/Z9GEBYV.png)
Forwarded port 33 on my router to my static ip address (http://i.imgur.com/KGNQ2Qk.png)
Setup flask to use my static ip and port: 33
I'm using the following code as a test webserver
from flask import Flask, request, redirect
app = Flask(__name__)
#app.route("/")
def hello_world():
return "Test 123 "
if __name__ == "__main__":
app.run(host="0.0.0.0", port="33")
When I open my browser to: http://192.168.1.11:33/ the page displays properly, I see "Test 123"
My problem comes when trying to connect to my webserver from my public ip address When I open my browser to http://xx.xxx.xxx.xx:30 (my ip address) all I see is "this site can't be reached, xx.xxx.xxx.xx refused to connect"
I've looked up all the stack overflow answers, I've done the following:
Turned off windows firewall
Changed host from "192.168.1.11" to "0.0.0.0"
Tried a different port
screenshot of code running and error shown: http://i.imgur.com/a05GvEs.png
My question is: What do I need to do to make my flask server visible from my public ip address?
Do you have DHCP activated on your router?
If yes do you see your host as 192.168.1.11 in there?
You have to use '0.0.0.0' on host, that tells Flask to listen on all addresses.
Try specifying the port with quotes as app.run(host="0.0.0.0", port="33")
change it to app.run(host= '0.0.0.0', port="33") to run on your machines IP address.
Documented on the Flask site under "Externally Visible Server" on the Quickstart page:
http://flask.pocoo.org/docs/0.10/quickstart/#a-minimal-application
Add port forwarding to port 33 in your router
Port forwarding explained here
http://www.howtogeek.com/66214/how-to-forward-ports-on-your-router/
You must give the public ip address/LAN ip address as an argument to app.run method.
When you don't provide host argument, it works fine with http://localhost:8888/ and http://127.0.0.1:888/, but not to access outside the system where you are running the REST services
Following is the example.
app.run(host="192.168.0.29",debug=True, port=8888)
You must try and use the same ip of the development server. Thus, for instance, if the dev server is running on a PC with the address 192.168.1.11
and port 33, other clients must point at the same address: 192.168.1.11:33.
As far as my small experience, it works with the debugger disabled, but I did not check if this is an essential prerequisite.
good luck
Every webservice should be run from different port address.Single service is running from a single port.

Categories