I'm trying to set up a webhook with python-telegram-bot and Nginx. I am faced with a problem, my bot doesn't get messages from telegram. I also tried to make GET/POST queries from the postman and I always get a "502 Bad Gateway" error. I also launched the netstat to monitor port 5000 where my telegram bot connects but it is always empty. It seems like webhook doesn't launch at all.
My Nginx default.conf file looks like the following:
upstream django {
server gunicorn:8000;
}
server {
listen 80;
server_name example.com www.example.com;
return 301 https://$server_name$request_uri;
}
server {
listen 443 ssl;
ssl on;
server_name example.com www.example.com;
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
access_log /var/log/nginx/nginx.vhost.access.log;
error_log /var/log/nginx/nginx.vhost.error.log;
location /TELEGRAM_TOKEN {
proxy_pass http://0.0.0.0:5000/TELEGRAM_TOKEN/;
}
location /static/ {
alias /static/;
}
location / {
proxy_pass http://example.com:8000;
}
}
And my telegram client code:
updater = Updater(api_token)
updater.dispatcher.add_handler(CommandHandler('start', start))
updater.dispatcher.add_handler(CallbackQueryHandler(button))
updater.dispatcher.add_handler(MessageHandler(Filters.text & ~Filters.command, custom_command))
jq = updater.job_queue
job_minute = jq.run_repeating(callback_minute, interval=5)
#updater.start_polling()
updater.start_webhook(listen="0.0.0.0", port=5000, url_path=api_token,
webhook_url=f'https://example.com/{api_token}')
updater.idle()
I also have Django options for the Nginx server but I've never seen any tutorial or documentation on how to tune the webhook with Django and it can be the reason for my problems.
Have anyone any idea about solving my problem?
CallMeStag, your advice to use the following code helped me solve the issue:
print(Bot(api_token).get_webhook_info()))
I had 2 problems with the Nginx config file
First: ssl on
It gave me an error connection refused and I deleted it
Second
I changed this
location /TELEGRAM_TOKEN {
proxy_pass http://0.0.0.0:5000/TELEGRAM_TOKEN/;
}
to this
location /TELEGRAM_TOKEN {
proxy_pass http://example.com:5000/TELEGRAM_TOKEN/;
}
and the webhook is now working.
Thank you.
Related
I have a AWS server runs on Nginx and which hosts a React application working fine on server.
Now I want a Django app for restframework to be available on the same server.
Iam following the Document and uploaded the Django app on the server and try to run the app by trying python3 manage.py runserver 0.0.0.0:8000. There is no error but I cannot access my ip with http://server_domain_or_IP:8000.
Nginx config at /etc/nginx/conf.d/example.org.conf
server {
listen 80 default_server;
server_name example.org;
return 301 https://example.org;
}
server {
listen 443 ssl;
server_name example.org;
ssl_certificate /etc/nginx/ssl/ssl_bundle.crt;
ssl_certificate_key /etc/nginx/ssl/example.key;
location / {
root /home/ubuntu/example/build;
index index.html index.htm;
}
}
Please help where am I going wrong?
So your Django is running on localhost:8000 and in your Nginx setup, you are not forwarding your request to that address. You have to match the domain request with your Django running server, In production, you should have something like Gunicorn
Try with -
upstream backend {
server localhost:8000;
}
server {
server_name example.com www.example.com;
location / {
include proxy_params;
proxy_pass http://backend;
}
this would work for non-https. You can add listen 443 ssl, and SSL certificates to make your server block listen only to HTTPS.
I'm trying to test a deployment config for a Django setup that works fine in development mode.
I have name-based routing via Nginx's ssl_preread module on a load balancer, and SSL terminates at another Nginx instance on the server itself where the requests are proxied to uwsgi by socket.
server {
server_name dev.domain.net;
listen 80 proxy_protocol;
listen [::]:80 proxy_protocol;
location / {
return 301 https://$host$request_uri;
}
}
server {
server_name dev.domain.net;
listen 443 ssl;
listen [::]:443 ssl;
location / {
include uwsgi_params;
uwsgi_pass unix:/run/uwsgi/website.sock;
}
location /favicon.ico {
access_log off; log_not_found off;
}
}
I have uwsgi set to log %(host) and %(referer), they match in the logs.
In my uwsgi_params I'm passing $host and $referer like so, since I'm using name-based routing I pick up the $server_name variable that triggered the Nginx response...
uwsgi_param HTTP_REFERER $server_name;
uwsgi_param HTTP_HOST $host;
Adding (or taking away) protocols and ports to these makes no difference. Taking them away predictably generates a Django ALLOWED_HOSTS debug error.
I've confirmed that my ALLOWED_HOSTS includes the $host. I've tried adding CSRF_TRUSTED_ORIGINS for the same $host variable. I've tried setting CSRF_COOKIE_DOMAIN for the same $host variable. I have CSRF_COOKIE_SECURE set to True per the docs recommendation.
No matter what combination of the above settings are used, I get:
Referer checking failed - Referer is malformed. on all POST requests.
Short answer: don't use the uwsgi unix socket, but rather use http-socket and send the proxy request to localhost over unencrypted http (in uwsgi ini file):
http-socket = 127.0.0.1:8001
In nginx, get rid of uwsgi proxy params and simply proxy_pass with proxy_protocol headers enabled:
server {
server_name dev.domain.net;
listen 443 ssl proxy_protocol;
listen [::]:443 ssl proxy_protocol;
location / {
proxy_pass http://127.0.0.1:8001;
}
location /favicon.ico {
access_log off; log_not_found off;
}
}
At that point you can enable all of the recommended deployment settings in the Django docs, explicitly declare your ALLOWED_HOSTS and everything works fine.
These are a quite silly series of hoops with no apparent correct set of answers, especially considering referers are client headers that are easily forged.
The better answer is Django needs to get rid of a client referer check in its CSRF mechanism, it's pointless and makes no sense...
Currently, I'm deploying a react app and using django as the backend API on an ubuntu nginx server. The react app is already online have a SSL certificate, but the backend API does not. By default, browsers can't show a http content on a https connection.
Do I need to get another SSL certificate afor the backend API? Or is there another way to do it?
Nginx conf file (for the frontend part. I'm not sure how to configure the backend):
The backend is currently running on xxx.xx.x.xx:8000 (using gunicorn --daemon --bind xxx.xx.x.xx:8000)
server {
server_name xxxxxx.com www.xxxxxx.com xxx.xx.x.xx;
root /var/www/frontend/build;
index index.html index.htm;
location / {
try_files $uri $uri/ /index.html =404;
}
listen 443 ssl;
ssl_certificate /etc/letsencrypt/live/fromnil.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/fromnil.com/privkey.pem;
include /etc/letsencrypt/options-ssl-nginx.conf;
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
}
server {
if ($host = www.xxxxxx.com) {
return 301 https://$host$request_uri;
}
if ($host = xxxxxx.com) {
return 301 https://$host$request_uri;
}
server_name xxxxxx.com www.xxxxxx.com xxx.xx.x.xx;
listen 80;
return 404;
}
Thanks
Found this link, but wasn't able to post a comment because my reputation is not enough. And I don't really understand. Can anyone help me?
How to deploy react and django in aws with a ssl and a domain
Fist of all sorry for my bad english.
I'm having a problem configuring LetsEncrypt in my webapp, i make it work now i can access using https://www.myproject.com but if i try to use www.myproject.com, myproject.com or even https://myproject.com without the www i always get the error ERR_TOO_MANY_REDIRECTS.
This is my nginx config in /etc/nginx/sites-available/myproject
server {
listen 80;
listen [::]:80;
server_name myproject.com www.myproject.com;
return 301 https://$server_name$request_uri;
}
server {
# SSL configuration
listen 443 ssl http2;
listen [::]:443 ssl http2;
include snippets/ssl-myproject.com.conf;
include snippets/ssl-params.conf;
location = /favicon.ico { access_log off; log_not_found off; }
location /static/ {
root /home/user;
}
location /media/ {
root /home/user;
}
location /.well-known {
alias /home/user/myproject/.well-known;
}
location / {
include proxy_params;
proxy_pass http://unix:/home/user/myproject.sock;
}
}
I check a lot of questions like mine but in php projects try the solutions but still not found one to solve my problem.
if helps i have to say that i have cloudflare free configure for my domain
Thanks!
FIX: If you use cloudflare in your web when you install SSL certificates have to put the SSL cloudflare configuration in Full or Full(strict).
I am trying to config a nginx server on an EC2 instance:
What I have done are:
nginx listening 443 with ssl configured
there is a webservice deployed on the ec2 localhost:8086/applications/, this is what I want nginx to proxy to
What I have now is:
location /applications/.* {
proxy_pass http://localhost:8086
proxy_redirect default
}
but this doesn't work, when I try POST with url https://<ip>/applications/?wsdl the nginx error.log reads like below:
[error]15692#0 *1 "/usr/share/nginx/html/applications/index.html" is not found (2: No such file or directory), client <my_ip>, server: , request "POST /applications/ HTTP/1.1", host: <the_host_ip>
Very noob about nginx here, your help will be appreciated, or direct me to wherever documenting this kind of config please.
You have some ;s missing in your configs and I don't think you need /applications/.* on your location
Try something like this:
listen 80;
server_name your.website.com;
location /applications {
proxy_pass http://localhost:8086;
proxy_redirect off;
}
Make sure you don't have something like this:
location / {
root html;
index index.html index.htm;
}
It works for me with the following example code. The version of nginx is 1.8.0.
listen 5554;
server_name localhost;
location / {
proxy_pass http://soap.example.com;
}