之前在DigitalOcean 的主機上用wordpress架了一個web site站台,只使用了 port 80, 後來在 443 port 架了 tornado, 滿神奇的,tornado 可以直接使用 letsencrypt 的憑證檔案。
後來發現 googlebot 會來parse 443 port 裡的資料。所以我希望 404 錯誤的資料就從80 port 裡重新取得一次,丟給Google.
取得 ssl 憑證
首先,是 letsencrypt 的 certbot 的官方說明:
https://certbot.eff.org/#ubuntuxenial-other
照上面教學的指令下,只用一行就可以產生憑證。知道網站的根目錄用這行(指令1號):
letsencrypt certonly --webroot -w /var/www/example -d example.com
如果你完全沒有網站,可以使用這行(指令2號):
letsencrypt certonly --standalone -d example.com -d www.example.com
指令1號,letsencrypt 會放東西在 webroot 目錄裡,然後letsencrypt用 80 port 連回我們伺服器進去測試。
指令2號,會自動產生一個 80 port 的 service,然後letsencrypt用 80 port 連回我們伺服器進去測試。
這2個指令,都會因此去使用 443 port,實際上原理不需要了解太多,certbot 寫的滿聰明的,會在畫面上有提醒。產生完,手動測一下 renew,沒問題的把把 renew 指令放進排程裡。
letsencrypt renew --dry-run --agree-tos
成功後就會在ubuntu的/etc/letsencrypt/archive/ 下面看到憑證了。
在 80和443 port 都已經被其他程式使用中的請況下,需要更進階的設定,參考看看這一篇:
apache AH00171: Graceful restart requested, doing restart
https://stackoverflow.max-everyday.com/2017/02/apache-graceful-restart/
例如:
letsencrypt certonly --standalone -d example.com --tls-sni-01-port 445 --http-01-port 82
修改Tornado的 ssl_options
tornado改程式,須追加此兩個檔案的路徑在ssl_options下面,並注意檔案權限要能被讀。
http_server = tornado.httpserver.HTTPServer(Application(),
ssl_options={
“certfile”: “cert.pem”, #自行填好路徑
“keyfile”: “privkey.pem”, #自行填好路徑
})
完成之後,研究一下 tornado 的官方文件:
http://www.tornadoweb.org/en/stable/web.html#tornado.web.Application.settings
要使用下面的這組設定值來完成自動轉發:
default_handler_class
anddefault_handler_args
: This handler will be used if no other match is found; use this to implement custom 404 pages (new in Tornado 3.2).
範例寫法:
import tornado.web
class BaseHandler(tornado.web.RequestHandler):
"""
Base handler gonna to be used instead of RequestHandler
"""
def write_error(self, status_code, **kwargs):
if status_code in [403, 404, 500, 503]:
self.write('Error %s' % status_code)
else:
self.write('BOOM!')
class ErrorHandler(tornado.web.ErrorHandler, BaseHandler):
"""
Default handler gonna to be used in case of 404 error
"""
pass
class MainHandler(BaseHandler):
"""
Main handler
"""
def get(self):
self.write('Hello world!')
- Settings. We need to define
default_handler_class
anddefault_handler_args
as well
settings = {
'default_handler_class': ErrorHandler,
'default_handler_args': dict(status_code=404)
}
- Application.
application = tornado.web.Application([
(r"/", MainHandler)
], **settings)
as result. all errors except 404 gonna be handled by BaseHandler. 404 – ErrorHandler. that’s it 🙂
我的轉發的 code:
def write_error(self, status_code, **kwargs): if status_code == 404: from lib import libHttp http_obj = libHttp.Http() http_url = "http://%s%s" % (self.request.host,self.request.uri) (new_html_string, http_code) = http_obj.get_http_response(http_url) self.set_status(http_code) if not new_html_string is None: self.write(new_html_string) return return super(BaseHandler, self).write_error(status_code, **kwargs)
我最後放棄這個作法,改安裝 Nginx(發音同engine x)是一個網頁伺服器,它能反向代理HTTP, HTTPS, SMTP, POP3, IMAP的協議鏈接,以及一個負載均衡器和一個HTTP緩存。
https://www.nginx.com/resources/wiki/start/topics/tutorials/install/
範例:
nginx 基礎設定教學
http://blog.hellojcc.tw/2015/12/07/nginx-beginner-tutorial/
相關文章:
apache AH00171: Graceful restart requested, doing restart
https://stackoverflow.max-everyday.com/2017/02/apache-graceful-restart/