簡體   English   中英

鳳凰服務器上的MIX_ENV = prod在PORT = 80時崩潰

[英]MIX_ENV=prod on a Phoenix server crashes on starting with PORT=80

我有一些混合問題, MIX_ENV=prod with mix phoenix.server ,它在啟動時失敗。 在Linode的Ubuntu 14.04上運行所有最新的(Elixir 1.0.5,Phoenix 0.14.0),除了Erlang(17.x,17.3我認為)。

$ MIX_ENV=prod PORT=80 mix phoenix.server
{"Kernel pid terminated",application_controller,"{application_start_failure,elirc_site,{{shutdown,{failed_to_start_child,'Elixir.ElircSite.Endpoint',{shutdown,{failed_to_start_child,'Elixir.Phoenix.Endpoint.Server',{shutdown,{failed_to_start_child,{ranch_listener_sup,'Elixir.ElircSite.Endpoint.HTTP'},{shutdown,{failed_to_start_child,ranch_acceptors_sup,{{badmatch,{error,eacces}},[{ranch_acceptors_sup,init,1,[{file,\"src/ranch_acceptors_sup.erl\"},{line,30}]},{supervisor,init,1,[{file,\"supervisor.erl\"},{line,243}]},{gen_server,init_it,6,[{file,\"gen_server.erl\"},{line,306}]},{proc_lib,init_p_do_apply,3,[{file,\"proc_lib.erl\"},{line,239}]}]}}}}}}}}},{'Elixir.ElircSite',start,[normal,[]]}}}"}

具體來說,我認為這部分是追蹤。

{{badmatch,{error,eacces}},[{ranch_acceptors_sup,init,1,[{file,\"src/ranch_acceptors_sup.erl\"},{line,30}]}

看起來您的服務器正在嘗試綁定到沒有root權限的受限端口(小於1024)。 嘗試使用更高端口,例如Phoenix的默認值4000.如果它需要在端口80上,要么以root身份運行,要么(更好)使用nginx代理它。

正如Nick Meharry指出你試圖在傳統上在Unix上的端口上運行Phoenix服務器進程,只有root可以綁定到(低端口(<1024))。

由於安全原因,不建議以root身份運行您的進程 - 接管該進程的攻擊者可以獲得對整個操作系統的root訪問權限。

通過在高端口(例如,4000)上運行服務器並使用簡單的iptables規則將連接從端口80轉發到端口4000來解決此問題更安全。請注意,計算機上的任何用戶都可以綁定到端口4000 - 所以你失去了低端口的額外保護。

另一個解決方案是允許某些程序( mixelixir )使用CAP_NET_BIND_SERVICE Linux內核功能(自2.6.24開始提供)綁定到1024以下的端口,該功能可以使用setcap設置。 但是,任何用戶仍然可以使用此可執行文件,除非它們僅通過使用適當的文件訪問權限對特定用戶可用。

我看到以下選項:

  1. 在前面使用apache / nginx作為鳳凰在其后面的更高端口上運行的代理 - Elixir的創建者,已經說過在這個問題線程中通常沒有必要這樣做。 如果你已經需要nginx用於其他東西(比如運行WP或提供靜態圖像),那么就這樣做吧。
  2. 從安全角度來看,以簡單但非常糟糕的方式運行。
  3. 使用IP表 - 簡單有效,但打破ipv6
  4. 使用setcap為特定二進制文件提供打開較低端口的能力。

我喜歡選項4。

要運行mix phoenix.server和類似命令,需要在BEAM二進制文件上運行setcap 你可以通過簡單地以root身份啟動服務器並執行ps -ef | grep beam來找到它 ps -ef | grep beam 在我的系統上,它是/usr/lib/erlang/erts-8.1/bin/beam.smp ,所以我運行:

sudo setcap CAP_NET_BIND_SERVICE=+eip /usr/lib/erlang/erts-8.1/bin/beam.smp

現在可以使用mix命令在普通端口上啟動服務器。 接下來,大概你會想要部署一個實際的elixir版本並將其作為服務運行。 同樣的策略也有效。 在您的發布版本創建的run_erl二進制文件上使用setcap 對於我的應用程序,它是:

sudo setcap CAP_NET_BIND_SERVICE=+eip /home/ubuntu/myapp/_build/prod/rel/myapp/erts-8.1/bin/run_erl

現在,一個upstart或systemd腳本也可以啟動服務器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM