Skip to content
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

[#41] feat(server): Add https support for Jetty server #860

Merged
merged 12 commits into from
Dec 5, 2023
Merged

[#41] feat(server): Add https support for Jetty server #860

merged 12 commits into from
Dec 5, 2023

Conversation

qqqttt123
Copy link
Contributor

@qqqttt123 qqqttt123 commented Nov 28, 2023

What changes were proposed in this pull request?

I add a https connector referring to the implement of Apache Livy(incubating).

Why are the changes needed?

Fix: #41

Does this PR introduce any user-facing change?

Yes, I add the documents.

How was this patch tested?

Manual test.

I run the command

# generate the key store
cd $JAVA_HOME
bin/keytool -genkeypair  -alias localhost \
        -keyalg RSA -keysize 4096 -keypass localhost \
        -sigalg SHA256withRSA \
        -keystore localhost.jks -storetype JKS -storepass localhost \
        -dname "cn=localhost,ou=localhost,o=localhost,l=beijing,st=beijing,c=cn" \
        -validity 36500
# generate the certificate
bin/keytool -export -alias localhost -keystore localhost.jks -file  localhost.crt -storepass localhost

# import the certificate
bin/keytool -import -alias localhost -keystore jre/lib/security/cacerts -file localhost.crt -storepass changeit -noprompt

# server's configuration
gravitino.server.webserver.host localhost
gravitino.server.webserver.httpsEnable true
gravitino.server.webserver.keyStorePath ${JAVA_HOME}/localhost.jks (Configuration doesn't support to resolve environment variable, so you should replace ${JAVA_HOME} with the actual value)
gravitino.server.webserver.keyStorePassword localhost
gravitino.server.webserver.managerPassword localhost

# user GravitinoClient to call the version api
String uri = "https://localhost:8443";
GravitinoClient client = GravitinoClient.builder(uri).build();
GravitinoVersion gravitinoVersion = client.getVersion();
# The result is successful.

@qqqttt123 qqqttt123 marked this pull request as draft November 28, 2023 09:02
@qqqttt123 qqqttt123 changed the title [#41] server: Add https support for Jetty Server [#41] feat(server): Add https support for Jetty Server Nov 28, 2023
Copy link

github-actions bot commented Nov 29, 2023

Code Coverage Report

Overall Project 65.78% -0.42% 🟢
Files changed 59.82% 🔴

Module Coverage
server-common 66.57% -10.82% 🔴
Files
Module File Coverage
server-common JettyServerConfig.java 92.69% -6.36% 🟢
JettyServer.java 46.23% -21.82% 🔴

@qqqttt123 qqqttt123 marked this pull request as ready for review November 29, 2023 12:16
docs/security.md Outdated
### Gravitino server's configuration
| Configuration item | Description | Default value | Since version |
|-----------------------------------------------|-----------------------------------------------|---------------|---------------|
| `gravitino.server.webserver.httpsEnable` | Enables https | `false` | 0.3.0 |
Copy link
Contributor

Choose a reason for hiding this comment

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

Shouldn't we use https as default?

Copy link
Contributor Author

@qqqttt123 qqqttt123 Nov 29, 2023

Choose a reason for hiding this comment

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

HTTPS will make deployment more complex. So we don't choose to enable the feature by default. Many other systems made a similar choice.

Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest changing to "gravitino.server.webserver.enableHttps"

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.

@qqqttt123 qqqttt123 changed the title [#41] feat(server): Add https support for Jetty Server [#41] feat(server): Add https support for Jetty server Nov 29, 2023
Copy link
Contributor

@mchades mchades left a comment

Choose a reason for hiding this comment

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

Usually, once HTTPS is set up, most services will configure redirection to redirect all HTTP traffic to HTTPS to ensure the security of communication. Should we support this ability?

serverConfig.getHost(),
serverConfig.getHttpPort(),
serverConfig.getHttpsPort());
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

user can not start services on both https and http at the same time?

Copy link
Contributor Author

@qqqttt123 qqqttt123 Nov 30, 2023

Choose a reason for hiding this comment

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

Livy chooses http or https. I follow the suggestion. Thanks.

Copy link
Contributor

Choose a reason for hiding this comment

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

OK, but should we tell the user in the document that if gravitino.server.webserver.httpsPort=true then all configurations about HTTP(such as HTTP port) will be invalidated?

Copy link
Contributor

Choose a reason for hiding this comment

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

I also have a concern about the convenience and compatibility of migration:

If the user wants to enable HTTPS after running the service on HTTP for a period of time, for your current implementation, they must complete all HTTP client refactoring before switching. It's a big matter for online service

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What's your suggestion?

Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest supporting both HTTP and HTTPS.

serverConfig.getHost(),
serverConfig.getHttpPort(),
serverConfig.getHttpsPort());
} else {
Copy link
Contributor

Choose a reason for hiding this comment

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

ditto

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.

@qqqttt123
Copy link
Contributor Author

Usually, once HTTPS is set up, most services will configure redirection to redirect all HTTP traffic to HTTPS to ensure the security of communication. Should we support this ability?

Could you give me some examples?

@qqqttt123 qqqttt123 closed this Nov 30, 2023
@qqqttt123 qqqttt123 reopened this Nov 30, 2023
@mchades
Copy link
Contributor

mchades commented Nov 30, 2023

Usually, once HTTPS is set up, most services will configure redirection to redirect all HTTP traffic to HTTPS to ensure the security of communication. Should we support this ability?

Could you give me some examples?

I'm referring to the web service, such as http://github.com, http://google.com, http://apple.com

connector.setReuseAddress(true);
return connector;
}

Copy link
Contributor

Choose a reason for hiding this comment

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

How to handle exceptions on https initialize. Would it be easy for the user to understand if the original exception is thrown?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

What exception should we handle?

Copy link
Contributor

@diqiu50 diqiu50 left a comment

Choose a reason for hiding this comment

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

Missing integration tests.

@qqqttt123
Copy link
Contributor Author

Missing integration tests.

Integration tests may be difficult. Some steps need human interaction.

@qqqttt123
Copy link
Contributor Author

qqqttt123 commented Nov 30, 2023

Missing integration tests.

I find I can add the option -no-prompt to skip human interaction. I will have a try to add a integration test.

docs/security.md Outdated Show resolved Hide resolved
Because HTTPS will protect the header of request from smuggling and HTTPS will be safer.
Both Gravitino server and Iceberg rest service can configure HTTPS.

### Gravitino server's configuration
Copy link
Contributor

Choose a reason for hiding this comment

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

Gravitino server and Iceberg REST server have it's configuration doc, I wonder whether it's proper to put security configuration here.

Copy link
Contributor Author

@qqqttt123 qqqttt123 Dec 1, 2023

Choose a reason for hiding this comment

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

It's ok for us not to add these configuration options in those documents. Spark also follows this document style.

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 you should add more doc example about how to configure https.

@qqqttt123
Copy link
Contributor Author

Add a warning log if we enable OAuth and HTTP.

@qqqttt123
Copy link
Contributor Author

Add a warning log if we enable OAuth and HTTP.

Fixed.

@qqqttt123
Copy link
Contributor Author

For documents, we just add some simple configuration options. I will polish the document in the next pr.

@qqqttt123
Copy link
Contributor Author

I have addressed the comments. @jerryshao Could you review this pr if you have time?

Copy link
Contributor

@jerryshao jerryshao left a comment

Choose a reason for hiding this comment

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

Have you tested with Gravitino Client and curl. As I remembered there will be some settings in the client side if client side auth is enable.

Also some other configurations like keystore type, trustStore, trustStorePassword, trustStoreType, algorithm probably are also required, can you please check the Spark's code SSLOptions.

docs/security.md Outdated
### Gravitino server's configuration
| Configuration item | Description | Default value | Since version |
|-----------------------------------------------|-----------------------------------------------|---------------|---------------|
| `gravitino.server.webserver.httpsEnable` | Enables https | `false` | 0.3.0 |
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest changing to "gravitino.server.webserver.enableHttps"

docs/security.md Outdated
### Iceberg REST service's configuration
| Configuration item | Description | Default value | Since version |
|------------------------------------------------------|-----------------------------------------------|---------------|---------------|
| `gravitino.auxService.iceberg-rest.httpsEnable` | Enables https | `false` | 0.3.0 |
Copy link
Contributor

Choose a reason for hiding this comment

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

Also 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.

I will fix.

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.


private AuthenticatorUtil() {}

public static boolean isEnableOAuth2() {
Copy link
Contributor

Choose a reason for hiding this comment

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

Basically not just oauth2, all the token based auth should be with https, otherwise it has a risk of token leakage.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

OK, I got 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.

@qqqttt123
Copy link
Contributor Author

Have you tested with Gravitino Client and curl. As I remembered there will be some settings in the client side if client side auth is enable.

Also some other configurations like keystore type, trustStore, trustStorePassword, trustStoreType, algorithm probably are also required, can you please check the Spark's code SSLOptions.

I have tested by GravitinoClient.

@jerryshao
Copy link
Contributor

jerryshao commented Dec 4, 2023

Have you tested with Gravitino Client and curl. As I remembered there will be some settings in the client side if client side auth is enable.
Also some other configurations like keystore type, trustStore, trustStorePassword, trustStoreType, algorithm probably are also required, can you please check the Spark's code SSLOptions.

I have tested by GravitinoClient.

My point is the second sentence.

@qqqttt123 qqqttt123 requested a review from jerryshao December 4, 2023 11:27
| `gravitino.server.webserver.keyStorePassword` | Password to the key store | `` | 0.3.0 |
| `gravitino.server.webserver.keyStoreType` | The type to the key store | `JKS` | 0.3.0 |
| `gravitino.server.webserver.managerPassword` | Manager password to the key store | `` | 0.3.0 |
| `gravitino.server.webserver.tlsProtocol` | TLS protocol to use. The protocol must be supported by JVM | none | 0.3.0 |
Copy link
Contributor

Choose a reason for hiding this comment

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

How do you configure this? and algorithm, it would be better to add more docs about 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.

OK, I will add more description referring the doc of Spark.

@jerryshao
Copy link
Contributor

I remembered that you have a sever side check for auth and HTTP, why do you remove that check?

@qqqttt123
Copy link
Contributor Author

I remembered that you have a sever side check for auth and HTTP, why do you remove that check?

Because we choose simpleAuth by default, the server always use the authentication mechanism, simple or OAuth. The server always faces the risk of token data leak.

Heng Qin added 2 commits December 4, 2023 20:31
docs/security.md Outdated

About `tlsProtocol`, the reference list of protocols can be found in the "Additional JSSE Standard Names" section of the Java security guide. The list for Java 8 can be found at <a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#jssenames">this</a>.
About `enableCipherAlgorithms`, the reference list of protocols can be found in the "JSSE Cipher Suite Names" section of the Java security guide. The list for Java 8 can be found at
<a href="https://docs.oracle.com/javase/8/docs/technotes/guides/security/StandardNames.html#ciphersuites">this</a>
Copy link
Contributor

Choose a reason for hiding this comment

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

Why do you use html links rather than markdown style?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Spark chooses this style. I will change it to markdown style. Fixed.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also are you going to add more security doc here in this PR, or you will split into a doc PR?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I will split into a doc PR.

.doc("Password to the key store")
.version("0.3.0")
.stringConf()
.createWithDefault("");
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 all these must-setting configurations should have no default empty string as value, right? Using default value here is a bit misleading.

Copy link
Contributor Author

@qqqttt123 qqqttt123 Dec 5, 2023

Choose a reason for hiding this comment

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

Yes, but they are must-setting configurations, it's weird if we use createWithOptional. It will report a error if we choose to use createWithDefault(null). So I choose to use empty value here.

Copy link
Contributor

Choose a reason for hiding this comment

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

I see, maybe we need to add a method in ConfigEntry called create to support configurations with no default value. @qqqttt123 can you please create an issue to track this?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created #950

@jerryshao jerryshao merged commit 68af8d6 into apache:main Dec 5, 2023
2 checks passed
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.

[Improvement] Add https support for Jetty Server
6 participants