Skip to content

Commit

Permalink
Merge pull request #268 from mageddo/dps-3-dns-server
Browse files Browse the repository at this point in the history
DPS 3 - Features
  • Loading branch information
mageddo authored Jan 31, 2023
2 parents 4571fde + b386d1b commit 63a302d
Show file tree
Hide file tree
Showing 38 changed files with 3,197 additions and 33 deletions.
6 changes: 1 addition & 5 deletions .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,9 @@
root = true

# Unix-style newlines with a newline ending every file
[*.go]
[*]
end_of_line = lf
insert_final_newline = true
charset = utf-8
indent_style = tab
indent_size = 2

[{*.java, *.gradle, *.yml, app/*package.json}]
indent_style = space
indent_size = 2
16 changes: 16 additions & 0 deletions README.alpha.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,25 @@ $ ./gradlew build nativeCompile &&\
build/native/nativeCompile/dns-proxy-server
```


## Run a container for testing

```
docker run --rm -it --hostname nginx.dev -e 'HOSTNAMES=nginx.com.br' nginx:1.15 bash
```
## x
```bash
docker-compose -f docker-compose-alpha.yml rm &&\
docker-compose -f docker-compose-alpha.yml build &&\
docker-compose -f docker-compose-alpha.yml run -T --rm arm7x86
```

Generate json reflect for all project

```
$ ./gradlew shadowJar
$ mkdir reflect &&\
$JAVA_HOME/bin/java -agentlib:native-image-agent=config-output-dir=./reflect -jar build/libs/dns-proxy-server*all.jar
```

34 changes: 31 additions & 3 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ buildscript {
plugins {
id "java"
id 'org.graalvm.buildtools.native' version '0.9.19'
id "com.github.johnrengelman.shadow" version "7.1.2"
}

repositories {
Expand Down Expand Up @@ -44,15 +45,24 @@ dependencies {
compileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.+'
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.+'

compileOnly(group: "com.mageddo.nativeimage", name: "reflection-config-generator", version: "2.3.+")
annotationProcessor(group: "com.mageddo.nativeimage", name: "reflection-config-generator", version: "2.3.+")

implementation 'com.google.dagger:dagger:2.44.+'
annotationProcessor 'com.google.dagger:dagger-compiler:2.44.+'

implementation group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.+'
implementation group: 'com.mageddo.tinyserver', name: 'tinyserver', version: '1.0.+'
implementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.14.+'
implementation group: "ch.qos.logback", name: "logback-classic", version: "1.2.+"

implementation group: 'com.mageddo.tinyserver', name: 'tinyserver', version: '1.0.+'

implementation group: 'dnsjava', name: 'dnsjava', version: '3.5.2'

implementation group: 'com.github.docker-java', name: 'docker-java-core', version: '3.2.14'
implementation group: 'com.github.docker-java', name: 'docker-java-transport-httpclient5', version: '3.2.14'

compileOnly(group: "com.mageddo.nativeimage", name: "reflection-config-generator", version: "2.4.+")
annotationProcessor(group: "com.mageddo.nativeimage", name: "reflection-config-generator", version: "2.4.+")

testCompileOnly group: 'org.projectlombok', name: 'lombok', version: '1.18.+'
testAnnotationProcessor group: 'org.projectlombok', name: 'lombok', version: '1.18.+'
testImplementation(group: "org.junit.jupiter", name: "junit-jupiter", version: "5.8.+")
Expand All @@ -65,3 +75,21 @@ test {
events "passed", "skipped", "failed"
}
}


def mainClassName = "com.mageddo.dnsproxyserver.App"

jar {
manifest {
attributes(
"Main-Class": mainClassName
)
}
}

shadowJar {
mergeServiceFiles()
transform(com.github.jengelman.gradle.plugins.shadow.transformers.PropertiesFileTransformer) {
mergeStrategy = "append"
}
}
14 changes: 10 additions & 4 deletions src/main/java/com/mageddo/dnsproxyserver/App.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package com.mageddo.dnsproxyserver;

public class App {
public static void main(String[] args) {
System.out.println("Hello World");
import com.mageddo.dnsproxyserver.dagger.Factory;

// start webserver
public class App {
public static void main(String[] args) throws InterruptedException {
final var factory = Factory.factory();

// start dns server
factory.dnsServerStarter().start();

// start webserver

// configurations

// setup as default dns

// install as service

Thread.currentThread().join();

}
}
20 changes: 20 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/config/Configs.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.mageddo.dnsproxyserver.config;

import com.mageddo.dnsproxyserver.server.dns.solver.RemoteSolverConfig;
import com.mageddo.dnsproxyserver.server.dns.SimpleServer;

public class Configs {
public static int findDnsServerPort() {
return 8053;
}

public static SimpleServer.Protocol findDnsServerProtocol() {
return SimpleServer.Protocol.BOTH;
}

public static RemoteSolverConfig findRemoverSolverConfig() {
return new RemoteSolverConfig()
.setIp(new byte[]{8, 8, 8, 8})
.setPort((short) 53);
}
}
46 changes: 46 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/dagger/DockerModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.mageddo.dnsproxyserver.dagger;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientImpl;
import com.github.dockerjava.httpclient5.ApacheDockerHttpClient;
import com.mageddo.dnsproxyserver.docker.DockerRepository;
import com.mageddo.dnsproxyserver.docker.DockerRepositoryDefault;
import dagger.Binds;
import dagger.Module;
import dagger.Provides;

import java.time.Duration;

@Module
public interface DockerModule {


@Binds
DockerRepository bind(DockerRepositoryDefault m);

@Provides
static DockerClient dockerClient() {
final var config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("unix:///var/run/docker.sock")
.withDockerTlsVerify(false)
// .withDockerCertPath("/home/user/.docker")
// .withRegistryUsername(registryUser)
// .withRegistryPassword(registryPass)
// .withRegistryEmail(registryMail)
// .withRegistryUrl(registryUrl)
.build();

final var httpClient = new ApacheDockerHttpClient.Builder()
.dockerHost(config.getDockerHost())
.sslConfig(config.getSSLConfig())
.maxConnections(5)
.connectionTimeout(Duration.ofMillis(300))
.responseTimeout(Duration.ofSeconds(3))
.build();

return DockerClientImpl.getInstance(config, httpClient);
}


}
24 changes: 24 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/dagger/Factory.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.mageddo.dnsproxyserver.dagger;

import com.mageddo.dnsproxyserver.server.dns.ServerStarter;
import com.mageddo.dnsproxyserver.server.dns.solver.Solver;
import dagger.Component;

import javax.inject.Singleton;
import java.util.Set;

@Singleton
@Component(modules = {MainModule.class, DockerModule.class})
public interface Factory {

ServerStarter dnsServerStarter();

Set<Solver> solvers();

static Factory factory() {
return DaggerFactory
.builder()
.build()
;
}
}
30 changes: 30 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/dagger/MainModule.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.mageddo.dnsproxyserver.dagger;

import com.mageddo.dnsproxyserver.config.Configs;
import com.mageddo.dnsproxyserver.server.dns.solver.DockerSolver;
import com.mageddo.dnsproxyserver.server.dns.solver.RemoteSolver;
import com.mageddo.dnsproxyserver.server.dns.solver.Solver;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.ElementsIntoSet;
import org.xbill.DNS.Resolver;
import org.xbill.DNS.SimpleResolver;

import java.util.Set;

@Module
public interface MainModule {

@ElementsIntoSet
@Provides
static Set<Solver> solvers(
RemoteSolver a, DockerSolver b
) {
return Set.of(a, b);
}

@Provides
static Resolver simpleResolver() {
return new SimpleResolver(Configs.findRemoverSolverConfig().toSocketAddress());
}
}
41 changes: 41 additions & 0 deletions src/main/java/com/mageddo/dnsproxyserver/docker/Docker.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
package com.mageddo.dnsproxyserver.docker;

import com.github.dockerjava.api.model.ContainerConfig;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.Collections;
import java.util.Set;
import java.util.stream.Collectors;

public class Docker {

public static final String HOSTNAME_ENV = "HOSTNAMES=";

public static String findContainerHostname(ContainerConfig config) {
final var hostname = config.getHostName();
if (StringUtils.isBlank(hostname)) {
return null;
}
final var domainName = config.getDomainName();
if (StringUtils.isBlank(domainName)) {
return hostname;
}
return String.format("%s.%s", hostname, domainName);
}

public static Set<String> findHostnameFromEnv(String[] envs) {
if (envs == null) {
return Collections.emptySet();
}
for (String env : envs) {
if (env.startsWith(HOSTNAME_ENV)) {
final var hosts = env.substring(HOSTNAME_ENV.length()).split("\s,\s");
return Arrays
.stream(hosts)
.collect(Collectors.toSet());
}
}
return Collections.emptySet();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.mageddo.dnsproxyserver.docker;

import com.github.dockerjava.api.command.InspectContainerResponse;
import lombok.extern.slf4j.Slf4j;

import java.util.Arrays;

@Slf4j
public class DockerNetworks {
public static String findBestIpMatching(InspectContainerResponse c, String... networksNames) {
final var networks = c.getNetworkSettings().getNetworks();
for (final var name : networksNames) {
if (!networks.containsKey(name)) {
continue;
}
final var ip = networks.get(name).getIpAddress();
log.debug("status=foundIp, network={}, container={}, ip={}", name, c.getName(), ip);
return ip;
}
log.debug("status=noIpFound, searchedNetworks={}, container={}", Arrays.toString(networksNames), c.getName());
return null;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.mageddo.dnsproxyserver.docker;

public interface DockerRepository {
/**
*
* @param host
* @return the host ip
*/
String findHostIp(String host);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.mageddo.dnsproxyserver.docker;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.InspectContainerResponse;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.util.Objects;
import java.util.Set;
import java.util.function.Predicate;

import static com.mageddo.dnsproxyserver.docker.Docker.findContainerHostname;
import static com.mageddo.dnsproxyserver.docker.Docker.findHostnameFromEnv;

@Slf4j
@Singleton
@AllArgsConstructor(onConstructor = @__({@Inject}))
public class DockerRepositoryDefault implements DockerRepository {

public static final String RUNNING_STATUS = "running";
private final DockerClient dockerClient;

@Override
public String findHostIp(String host) {
final var stopWatch = StopWatch.createStarted();
final var activeContainers = this.dockerClient
.listContainersCmd()
.withStatusFilter(Set.of(RUNNING_STATUS))
.withLimit(1024)
// .withNetworkFilter()
.exec();

final var foundIp = activeContainers
.stream()
.map(it -> this.dockerClient.inspectContainerCmd(it.getId()).exec())
.filter(matchingHostName(host))
.map(c -> DockerNetworks.findBestIpMatching(c, buildNetworks(c)))
.findFirst()
.orElse(null);
log.debug("status=findDone, host={}, found={}, time={}", host, foundIp, stopWatch.getTime());
return foundIp;
}

String[] buildNetworks(InspectContainerResponse c) {
return new String[]{"bridge"};
}

static Predicate<InspectContainerResponse> matchingHostName(String host) {
return it -> {
if (Objects.equals(findContainerHostname(it.getConfig()), host)) {
return true;
}
return findHostnameFromEnv(it.getConfig().getEnv()).contains(host);
};
}
}
Loading

0 comments on commit 63a302d

Please sign in to comment.