Skip to content

Commit

Permalink
Setup a default AWS profile under config, don't read ~/.aws.
Browse files Browse the repository at this point in the history
Signed-off-by: dblock <dblock@amazon.com>
  • Loading branch information
dblock committed May 9, 2023
1 parent 5a36e78 commit 29f2369
Show file tree
Hide file tree
Showing 15 changed files with 112 additions and 86 deletions.
42 changes: 0 additions & 42 deletions plugins/discovery-ec2/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -84,50 +84,8 @@ tasks.named("bundlePlugin").configure {
}
}

tasks.register("writeTestJavaPolicy") {
doLast {
final File tmp = file("${buildDir}/tmp")
if (tmp.exists() == false && tmp.mkdirs() == false) {
throw new GradleException("failed to create temporary directory [${tmp}]")
}
final File javaPolicy = file("${tmp}/java.policy")
if (BuildParams.inFipsJvm) {
javaPolicy.write(
[
"grant {",
" permission java.security.SecurityPermission \"putProviderProperty.BCFIPS\";",
" permission java.security.SecurityPermission \"putProviderProperty.BCJSSE\";",
" permission java.lang.RuntimePermission \"getProtectionDomain\";",
" permission java.util.PropertyPermission \"java.runtime.name\", \"read\";",
" permission org.bouncycastle.crypto.CryptoServicesPermission \"tlsAlgorithmsEnabled\";",
" permission java.lang.RuntimePermission \"accessClassInPackage.sun.security.internal.spec\";",
" permission java.lang.RuntimePermission \"accessDeclaredMembers\";",
" permission java.util.PropertyPermission \"intellij.debug.agent\", \"read\";",
" permission java.util.PropertyPermission \"intellij.debug.agent\", \"write\";",
" permission org.bouncycastle.crypto.CryptoServicesPermission \"exportSecretKey\";",
" permission org.bouncycastle.crypto.CryptoServicesPermission \"exportPrivateKey\";",
" permission java.io.FilePermission \"\${javax.net.ssl.trustStore}\", \"read\";",
" permission java.util.PropertyPermission \"aws.ec2MetadataServiceEndpoint\", \"write\";",
" permission java.io.FilePermission \"\${user.home}/.aws/config\", \"read\";",
" permission java.io.FilePermission \"\${user.home}/.aws/credentials\", \"read\";",
"};"
].join("\n")
)
} else {
javaPolicy.write(
[
"grant {",
" permission java.util.PropertyPermission \"aws.ec2MetadataServiceEndpoint\", \"write\";",
" permission java.io.FilePermission \"\${user.home}/.aws/config\", \"read\";",
" permission java.io.FilePermission \"\${user.home}/.aws/credentials\", \"read\";",
"};"
].join("\n"))
}
}
}

tasks.named("test").configure {
dependsOn "writeTestJavaPolicy"
// this is needed for insecure plugins, remove if possible!
systemProperty 'tests.artifact', project.name

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
import java.util.function.Function;

interface AwsEc2Service extends Closeable {

Setting<Boolean> AUTO_ATTRIBUTE_SETTING = Setting.boolSetting("cloud.node.auto_attributes", false, Property.NodeScope);

class HostType {
Expand Down Expand Up @@ -125,5 +126,4 @@ class HostType {
* @param clientSettings the new refreshed settings
*/
void refreshAndClearCache(Ec2ClientSettings clientSettings);

}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
import org.opensearch.OpenSearchException;
import org.opensearch.common.Strings;
import org.opensearch.common.util.LazyInitializable;
import org.opensearch.common.SuppressForbidden;
import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider;
import software.amazon.awssdk.auth.credentials.StaticCredentialsProvider;
import software.amazon.awssdk.http.apache.ApacheHttpClient;
Expand All @@ -50,9 +51,9 @@
import software.amazon.awssdk.core.retry.RetryPolicy;
import java.util.concurrent.atomic.AtomicReference;
import software.amazon.awssdk.core.client.config.ClientOverrideConfiguration;
import software.amazon.awssdk.profiles.ProfileFileSystemSetting;

class AwsEc2ServiceImpl implements AwsEc2Service {

private static final Logger logger = LogManager.getLogger(AwsEc2ServiceImpl.class);

private final AtomicReference<LazyInitializable<AmazonEc2ClientReference, OpenSearchException>> lazyClientReference =
Expand All @@ -72,6 +73,8 @@ protected Ec2Client buildClient(
ClientOverrideConfiguration overrideConfiguration,
String endpoint
) {
SocketAccess.doPrivilegedVoid(AwsEc2ServiceImpl::setDefaultAwsProfilePath);

Ec2ClientBuilder builder = Ec2Client.builder()
.overrideConfiguration(overrideConfiguration)
.httpClientBuilder(apacheHttpClientBuilder)
Expand Down Expand Up @@ -161,4 +164,15 @@ public void close() {
clientReference.reset();
}
}

// AWS v2 SDK load a default profile from $user_home, which is restricted. Use OpenSearch configuration path.
@SuppressForbidden(reason = "Prevent AWS SDK v2 from using ~/.aws/config and ~/.aws/credentials.")
static void setDefaultAwsProfilePath() {
if (ProfileFileSystemSetting.AWS_SHARED_CREDENTIALS_FILE.getStringValue().isEmpty()) {
System.setProperty(ProfileFileSystemSetting.AWS_SHARED_CREDENTIALS_FILE.property(), System.getProperty("opensearch.path.conf"));
}
if (ProfileFileSystemSetting.AWS_CONFIG_FILE.getStringValue().isEmpty()) {
System.setProperty(ProfileFileSystemSetting.AWS_CONFIG_FILE.property(), System.getProperty("opensearch.path.conf"));
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,4 @@ static Ec2ClientSettings getClientSettings(Settings settings) {
);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ final class SocketAccess {

private SocketAccess() {}

public static void doPrivilegedVoid(Runnable action) {
SpecialPermission.check();
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
action.run();
return null;
});
}

public static <T> T doPrivileged(PrivilegedAction<T> operation) {
SpecialPermission.check();
return AccessController.doPrivileged(operation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,10 @@ grant {

permission java.lang.reflect.ReflectPermission "suppressAccessChecks";

permission java.util.PropertyPermission "aws.sharedCredentialsFile", "read,write";
permission java.util.PropertyPermission "aws.configFile", "read,write";
permission java.util.PropertyPermission "aws.region", "read,write";
permission java.util.PropertyPermission "opensearch.path.conf", "read,write";

permission java.io.FilePermission "config", "read";
};
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@
import static java.nio.charset.StandardCharsets.UTF_8;

@SuppressForbidden(reason = "use a http server")
public abstract class AbstractEC2MockAPITestCase extends OpenSearchTestCase {
public abstract class AbstractEc2MockAPITestCase extends OpenSearchTestCase {

protected HttpServer httpServer;

Expand All @@ -75,7 +75,7 @@ public abstract class AbstractEC2MockAPITestCase extends OpenSearchTestCase {
public void setUp() throws Exception {
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress(), 0), 0);
httpServer.start();
threadPool = new TestThreadPool(EC2RetriesTests.class.getName());
threadPool = new TestThreadPool(Ec2RetriesTests.class.getName());
transportService = createTransportService();
super.setUp();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,12 @@
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;

public class AwsEc2ServiceImplTests extends OpenSearchTestCase {
public class AwsEc2ServiceImplTests extends OpenSearchTestCase implements ConfigPathSupport {
@Override
public void setUp() throws Exception {
super.setUp();
setUpAwsProfile();
}

public void testAwsCredentialsWithSystemProviders() {
final AwsCredentialsProvider credentialsProvider = AwsEc2ServiceImpl.buildCredentials(
Expand Down Expand Up @@ -177,7 +182,6 @@ public void testAWSConfigurationWithAwsSettings() {

// retry policy
RetryPolicy retryPolicyConfiguration = AwsEc2ServiceImpl.buildRetryPolicy(logger, Ec2ClientSettings.getClientSettings(settings));

assertThat(retryPolicyConfiguration.numRetries(), is(10));

// TODO: AwsEc2ServiceImpl.buildCredentials(logger, Ec2ClientSettings.getClientSettings(settings));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* SPDX-License-Identifier: Apache-2.0
*
* The OpenSearch Contributors require contributions made to
* this file be licensed under the Apache-2.0 license or a
* compatible open source license.
*/

package org.opensearch.discovery.ec2;

import org.opensearch.common.io.PathUtils;

import java.nio.file.Path;

/**
* The trait that adds the config path and AWS profile setup to the test cases.
*/
interface ConfigPathSupport {
default Path configPath() {
return PathUtils.get("config");
}

default public void setUpAwsProfile() throws Exception {
SocketAccess.doPrivileged(() -> System.setProperty("opensearch.path.conf", configPath().toString()));
SocketAccess.doPrivileged(() -> System.setProperty("aws.region", "us-east-1"));
SocketAccess.doPrivilegedVoid(AwsEc2ServiceImpl::setDefaultAwsProfilePath);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,13 @@
import static org.hamcrest.Matchers.instanceOf;
import static org.hamcrest.Matchers.is;

public class Ec2DiscoveryPluginTests extends OpenSearchTestCase {
public class Ec2DiscoveryPluginTests extends OpenSearchTestCase implements ConfigPathSupport {

@Override
public void setUp() throws Exception {
super.setUp();
setUpAwsProfile();
}

private Settings getNodeAttributes(Settings settings, String url) {
final Settings realSettings = Settings.builder().put(AwsEc2Service.AUTO_ATTRIBUTE_SETTING.getKey(), true).put(settings).build();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@
import static org.hamcrest.Matchers.is;

@SuppressForbidden(reason = "use a http server")
public class Ec2DiscoveryTests extends AbstractEC2MockAPITestCase {
public class Ec2DiscoveryTests extends AbstractEc2MockAPITestCase implements ConfigPathSupport {

private static final String SUFFIX_PRIVATE_DNS = ".ec2.internal";
private static final String PREFIX_PRIVATE_DNS = "mock-ip-";
Expand All @@ -82,6 +82,12 @@ public class Ec2DiscoveryTests extends AbstractEC2MockAPITestCase {

private Map<String, TransportAddress> poorMansDNS = new ConcurrentHashMap<>();

@Override
public void setUp() throws Exception {
super.setUp();
setUpAwsProfile();
}

protected MockTransportService createTransportService() {
final Transport transport = new MockNioTransport(
Settings.EMPTY,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,16 @@
* They aren't.
*/
@SuppressForbidden(reason = "use http server")
public class Ec2NetworkTests extends OpenSearchTestCase {
public class Ec2NetworkTests extends OpenSearchTestCase implements ConfigPathSupport {

private static HttpServer httpServer;

@Override
public void setUp() throws Exception {
super.setUp();
setUpAwsProfile();
}

@BeforeClass
public static void startHttp() throws Exception {
httpServer = HttpServer.create(new InetSocketAddress(InetAddress.getLoopbackAddress().getHostAddress(), 0), 0);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,13 @@
import static org.hamcrest.Matchers.is;

@SuppressForbidden(reason = "use a http server")
public class EC2RetriesTests extends AbstractEC2MockAPITestCase {
public class Ec2RetriesTests extends AbstractEc2MockAPITestCase implements ConfigPathSupport {

@Override
public void setUp() throws Exception {
super.setUp();
setUpAwsProfile();
}

@Override
protected MockTransportService createTransportService() {
Expand Down
Loading

0 comments on commit 29f2369

Please sign in to comment.