Skip to content

ssl deproxy client and server #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 21 commits into from
Closed

ssl deproxy client and server #9

wants to merge 21 commits into from

Conversation

vladtcvs
Copy link
Contributor

Fixing message parsing

work on https client

@vladtcvs vladtcvs force-pushed the vlad-https branch 2 times, most recently from b42c3aa to 1cd179d Compare May 15, 2018 12:44
@vladtcvs
Copy link
Contributor Author

This PR is for tempesta-tech/tempesta#737

@vladtcvs vladtcvs changed the title In progress: ssl client In progress: ssl deproxy client and server May 15, 2018
Copy link
Contributor

@vankoven vankoven left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As addition, there still lack of tests documentation, which was one of the most important requirements.

__license__ = 'GPL2'

rootCA = """-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIJAPP794tWF2qsMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNV
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The certificates and keys are defined twice: in tls/ directory and in this file. Why the repetition is required?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not required. They should be deleted ftom tls/

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we should store them in tls directory? We will also need the certificates for stress tests.

'log_file': 'tests_log.log'},
'log_file': 'tests_log.log',
'tmpdir': '/tmp/host',
'ip': '127.0.0.1'},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Configuration is confusing and mixed up. It was assumed that framework and client - are the same node and can't exist without each other, especially if deproxy-based tests are used. But I see the reason why it's important to run stress tester on other node: TfwBomber. Since it kernel module which heavily relies on Tempesta code, system will crash on bugs and no tests results will be saved.

I'm not happy about splitting framework and client nodes: when developing tests, you have to always remember, what is the type of current client and which node to use. But I don't see a good solution here.

Since the splitting is required, then explicit sections framework, stress_tester, tempesta, backendsare required. Putting everything ingeneral` section is worst way possible.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also the splitting is half-done. Client node is still hardcoded to be localhost only. See the check() function here.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good solution is to find good way to run deproxy client and servers on remote nodes.

@@ -47,7 +47,9 @@ def defaults(self):
self.config.read_dict({'General': {'verbose': '0',
'duration': '10',
'concurrent_connections': '10',
'log_file': 'tests_log.log'},
'log_file': 'tests_log.log',
'tmpdir': '/tmp/host',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tmpdir: configuration key with absolutely the same meaning in other nodes is workdir. Please keep same names for options with the same meaning.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

},
]

def test_1(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't see usage of Tempesta itself. Client connects directly to nginx.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, this tests checks only client and server. Tests for tempesta will be added later

@@ -15,7 +15,7 @@
__license__ = 'GPL2'

# Don't remove files from remote node. Helpful for tests development.
DEBUG_FILES = False
DEBUG_FILES = True
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See this change again and again in your PRs and evey time it's dirty commit.

'<<<<<\n%s>>>>>'
% self.request_buffer))
self.send_response(self.response_bad_request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Connection must be closed after parsing error. It's bad idea to keep connection open and parse further requests.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be handle_parsing_error() would be handy helpful function? it'll send and error (if asked) and close the connection. We have more tests, where the behaviour is going to be pretty useful.

raise NotImplementedError("Not implemented 'wait_for_connections'")

@abc.abstractmethod
def recieve_request(self, request, connection):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm confused but I rather often misspell receive as recieve. It's copy-paste, but the spelling should be fixed :-]

class SSLStaticDeproxyServer(BaseAsyncoreDeproxyServer):

def __init__(self, cert, cert_key, *args, **kwargs):
self.response = kwargs['response']
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why response is defined for SSL servver, but not defined for non-SSL socket. The only differens between them must be init_socket finction

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

? both ssl and non-ssl have 'response'


return srv

def create_srv_deproxy_ssl(server):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think, there should be only one helper function to create appropriate server, since all required variables are taken from server dictionary.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is different functions because they creates different classes. I've used 1 class - 1 creation function method

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just asked because the functions look very close. I was expecting to see fabric pattern here: single function which creates the right class according to it's description. But it's a part of __create_client() function, which is the fabric actually, i missed that, sorry.


def create_srv_deproxy(server):
ka = "close"
if server.has_key('connection_header'):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is connection_header? Server class must not add it's own headers when sending responses. The exact message to be send must be defined in test. No modifications inside server or client are allowed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I've confused. Of course, there should be not 'close' or 'keep_alive', but amount of responses before closing connection

@vladtcvs vladtcvs changed the title In progress: ssl deproxy client and server ssl deproxy client and server May 17, 2018
@vladtcvs vladtcvs force-pushed the vlad-https branch 3 times, most recently from cd30b23 to 3fee6ce Compare May 18, 2018 12:55

def init_socket(self):
self.s = socket.socket()
#self.ssl_socket = ssl.SSLSocket(sock=self.s,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Seems like the code was commented out for the troubleshooting, but the right version wasn't returned back. Need to fix it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed, commented code is removed

BaseAsyncoreClient.recieve_response(self, response)

def init_socket(self):
self.s = socket.socket()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

asyncore.dispatcher uses self.socket for the interaction, why self.s is needed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

self.s - raw socket. Later, in make_connect, it is wrapped with ssl socket, and this ssl socket is setted as self.socket

'<<<<<\n%s>>>>>'
% self.request_buffer))
self.send_response(self.response_bad_request)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be handle_parsing_error() would be handy helpful function? it'll send and error (if asked) and close the connection. We have more tests, where the behaviour is going to be pretty useful.


return srv

def create_srv_deproxy_ssl(server):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just asked because the functions look very close. I was expecting to see fabric pattern here: single function which creates the right class according to it's description. But it's a part of __create_client() function, which is the fabric actually, i missed that, sorry.

@@ -220,6 +220,9 @@ def create_node(host):
return RemoteNode(host, hostname, workdir, username, port)
return LocalNode(host, hostname, workdir)

def create_host_node():
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See client. It also has no real hostname field, it's hardcoded to be localhost in tf_cfg.py.

__license__ = 'GPL2'

rootCA = """-----BEGIN CERTIFICATE-----
MIIDZjCCAk6gAwIBAgIJAPP794tWF2qsMA0GCSqGSIb3DQEBCwUAMEgxCzAJBgNV
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be we should store them in tls directory? We will also need the certificates for stress tests.

@vladtcvs
Copy link
Contributor Author

See client. It also has no real hostname field, it's hardcoded to be localhost in tf_cfg.py.

It's wrong idea.

@vladtcvs vladtcvs closed this Jul 19, 2018
@krizhanovsky krizhanovsky deleted the vlad-https branch July 1, 2019 14:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants