问题
I write a tornado service as the Amazon SNS endpoint.
class TestHandler(tornado.web.RequestHandler):
def get(self):
logging.info('get')
self.sns()
self.write(self.request.body.decode('utf-8'))
def post(self):
logging.info('post')
self.sns()
self.write(self.request.body.decode('utf-8'))
def sns(self):
headers = self.request.headers
logging.info('HEADER: {}'.format(headers))
arn = headers.get('x-amz-sns-subscription-arn')
obj = json.loads(self.request.body)
if headers.get('x-amz-sns-message-type') == 'SubscriptionConfirmation':
logging.info('REQUEST: {}'.format(self.request))
subscribe_url = obj[u'SubscribeURL']
logging.info('URL:{}'.format(subscribe_url))
return '<Arn %r>' % arn
elif headers.get('x-amz-sns-message-type') == 'UnsubscribeConfirmation':
logging.info('Unsubscription')
elif headers.get('x-amz-sns-message-type') == 'Notification':
logging.info('Unsubscription')
return '', 200
But when I subscribe the endpoint to SNS, I didn't get any HTTP POST request. No logs was printed. So I tried to do curl
instead, and the logs shows it fine. I'm more convinced that SNS didn't send the request rather than my endpoint didn't receive it. I have no idea how to proceed. Please help. Thanks.
回答1:
Right, the outside traffic might get blocked, but I can hit the endpoint (not EC2) from my local machine.
This misses the point. You have to allow inbound connectivity from the Internet before SNS can access your http(s) endpoint. SNS does not have a back door to your instances.
The source IP address ranges for SNS notifications are published, so you can allow them in your security group...
https://forums.aws.amazon.com/ann.jspa?annID=1649
However, you need to be aware that the list is subject to change, so the best practice may be to make your endpoint globally-accessible.
It is also important to validate the messages using the signature provided, as well as to validate the public key of the certificate in the message by verifying that the URL for the certificate is legitimately associated with SNS, and by fetching the cert with HTTPS and validating the certificate provided during that TLS request as legitimately belonging to Amazon.
http://docs.aws.amazon.com/sns/latest/dg/SendMessageToHttp.verify.signature.html
来源:https://stackoverflow.com/questions/28867214/cannot-get-http-subscription-confirmation-request