使用 nginx 将 gRPC 流量从 HTTPS 重定向到 HTTP
Redirect gRPC traffic using nginx from HTTPS to HTTP
我计划在特殊用例中使用 nginx 重定向 HTTPS 和 HTTP gRPC 流量。我能够使用 hello world 示例重现问题。我使用的主要文档是 [Introducing gRPC Support with NGINX 1.13.10][1] 和 [Nginx as Reverse Proxy with GRPC][2].
首先,我使用
为 ssl 连接创建了证书文件
openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt -subj '/CN=localhost'
当我关注这篇文章时,我能够成功地将流量从安全的 grpc client 路由到安全的 grpc server。但是,我的用例需要将流量从安全的 nginx 端口转发到 insecure grpc 服务器。下面附上客户端,nginx.conf 和服务器代码。
nginx.conf(需要将流量重新路由到不安全的端口)
upstream dev {
server localhost:1338;
}
server {
listen 1449 ssl http2;
ssl_certificate /ssl/server.crt; #Enter you certificate location
ssl_certificate_key /ssl/server.key;
location /helloworld.Greeter {
grpc_pass grpcs://dev;
}
}
client.py(包括用于访问 nginx 安全端点的 ssl 证书)
from __future__ import print_function
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
host = 'localhost'
port = 1449
with open('/home/ubuntu/Documents/ludex_repos/nginx-grpc/server.crt', 'rb') as f:
trusted_certs = f.read()
credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
with grpc.secure_channel(f'{host}:{port}', credentials) as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print(f"========================Greeter client received: {response.message}===============================")
if __name__ == '__main__':
logging.basicConfig()
run()
server.py(端口不安全)
from concurrent import futures
import time
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
port = '1338'
with open('/ssl/server.key', 'rb') as f:
private_key = f.read()
with open('/ssl/server.crt', 'rb') as f:
certificate_chain = f.read()
server_credentials = grpc.ssl_server_credentials(((private_key, certificate_chain,),))
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
**If I change this to a secure port then it routes traffic correctly via nginx**
#server.add_secure_port('[::]:'+port, server_credentials)
server.add_insecure_port('[::]:'+port)
print("Server Started...")
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
logging.basicConfig()
serve()
安全到安全响应
========================Greeter client received: Hello, you!===============================
安全到不安全的响应
Traceback (most recent call last):
File "greeter_client.py", line 45, in <module>
run()
File "greeter_client.py", line 39, in run
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
File "/home/ubuntu/anaconda3/envs/fp/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/ubuntu/anaconda3/envs/fp/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Received http2 header with status: 502"
debug_error_string = "{"created":"@1641485952.541123035","description":"Received http2 :status header with non-200 OK status","file":"src/core/ext/filters/http/client/http_client_filter.cc","file_line":132,"grpc_message":"Received http2 header with status: 502","grpc_status":14,"value":"502"}"
>
我知道反向代理是可能的,我已经看到使用网页将流量从 https 转发到 http 的示例,但我不确定是否可以使用 gRPC 流量来实现?
[1]: https://www.nginx.com/blog/nginx-1-13-10-grpc/
[2]: https://medium.com/nirman-tech-blog/nginx-as-reverse-proxy-with-grpc-820d35642bff
尝试使用 grpc_pass grpc://...
而不是 grpcs://...
这篇更新的博客 post 可能会有所帮助:https://www.nginx.com/blog/deploying-nginx-plus-as-an-api-gateway-part-3-publishing-grpc-services/
我计划在特殊用例中使用 nginx 重定向 HTTPS 和 HTTP gRPC 流量。我能够使用 hello world 示例重现问题。我使用的主要文档是 [Introducing gRPC Support with NGINX 1.13.10][1] 和 [Nginx as Reverse Proxy with GRPC][2].
首先,我使用
为 ssl 连接创建了证书文件openssl req -newkey rsa:2048 -nodes -keyout server.key -x509 -days 365 -out server.crt -subj '/CN=localhost'
当我关注这篇文章时,我能够成功地将流量从安全的 grpc client 路由到安全的 grpc server。但是,我的用例需要将流量从安全的 nginx 端口转发到 insecure grpc 服务器。下面附上客户端,nginx.conf 和服务器代码。
nginx.conf(需要将流量重新路由到不安全的端口)
upstream dev {
server localhost:1338;
}
server {
listen 1449 ssl http2;
ssl_certificate /ssl/server.crt; #Enter you certificate location
ssl_certificate_key /ssl/server.key;
location /helloworld.Greeter {
grpc_pass grpcs://dev;
}
}
client.py(包括用于访问 nginx 安全端点的 ssl 证书)
from __future__ import print_function
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
def run():
# NOTE(gRPC Python Team): .close() is possible on a channel and should be
# used in circumstances in which the with statement does not fit the needs
# of the code.
host = 'localhost'
port = 1449
with open('/home/ubuntu/Documents/ludex_repos/nginx-grpc/server.crt', 'rb') as f:
trusted_certs = f.read()
credentials = grpc.ssl_channel_credentials(root_certificates=trusted_certs)
with grpc.secure_channel(f'{host}:{port}', credentials) as channel:
stub = helloworld_pb2_grpc.GreeterStub(channel)
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
print(f"========================Greeter client received: {response.message}===============================")
if __name__ == '__main__':
logging.basicConfig()
run()
server.py(端口不安全)
from concurrent import futures
import time
import logging
import grpc
import helloworld_pb2
import helloworld_pb2_grpc
_ONE_DAY_IN_SECONDS = 60 * 60 * 24
class Greeter(helloworld_pb2_grpc.GreeterServicer):
def SayHello(self, request, context):
return helloworld_pb2.HelloReply(message='Hello, %s!' % request.name)
def serve():
port = '1338'
with open('/ssl/server.key', 'rb') as f:
private_key = f.read()
with open('/ssl/server.crt', 'rb') as f:
certificate_chain = f.read()
server_credentials = grpc.ssl_server_credentials(((private_key, certificate_chain,),))
server = grpc.server(futures.ThreadPoolExecutor(max_workers=10))
helloworld_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
**If I change this to a secure port then it routes traffic correctly via nginx**
#server.add_secure_port('[::]:'+port, server_credentials)
server.add_insecure_port('[::]:'+port)
print("Server Started...")
server.start()
try:
while True:
time.sleep(_ONE_DAY_IN_SECONDS)
except KeyboardInterrupt:
server.stop(0)
if __name__ == '__main__':
logging.basicConfig()
serve()
安全到安全响应
========================Greeter client received: Hello, you!===============================
安全到不安全的响应
Traceback (most recent call last):
File "greeter_client.py", line 45, in <module>
run()
File "greeter_client.py", line 39, in run
response = stub.SayHello(helloworld_pb2.HelloRequest(name='you'))
File "/home/ubuntu/anaconda3/envs/fp/lib/python3.8/site-packages/grpc/_channel.py", line 946, in __call__
return _end_unary_response_blocking(state, call, False, None)
File "/home/ubuntu/anaconda3/envs/fp/lib/python3.8/site-packages/grpc/_channel.py", line 849, in _end_unary_response_blocking
raise _InactiveRpcError(state)
grpc._channel._InactiveRpcError: <_InactiveRpcError of RPC that terminated with:
status = StatusCode.UNAVAILABLE
details = "Received http2 header with status: 502"
debug_error_string = "{"created":"@1641485952.541123035","description":"Received http2 :status header with non-200 OK status","file":"src/core/ext/filters/http/client/http_client_filter.cc","file_line":132,"grpc_message":"Received http2 header with status: 502","grpc_status":14,"value":"502"}"
>
我知道反向代理是可能的,我已经看到使用网页将流量从 https 转发到 http 的示例,但我不确定是否可以使用 gRPC 流量来实现? [1]: https://www.nginx.com/blog/nginx-1-13-10-grpc/ [2]: https://medium.com/nirman-tech-blog/nginx-as-reverse-proxy-with-grpc-820d35642bff
尝试使用 grpc_pass grpc://...
而不是 grpcs://...
这篇更新的博客 post 可能会有所帮助:https://www.nginx.com/blog/deploying-nginx-plus-as-an-api-gateway-part-3-publishing-grpc-services/