1
0
Fork 1
mirror of https://gitlab.com/mangadex-pub/mangadex_at_home.git synced 2024-01-19 02:48:37 +00:00

Cut 2.0.1

This commit is contained in:
carbotaniuman 2021-05-27 14:53:54 -05:00
parent 1ef35244d7
commit 785dc1ed7f
7 changed files with 57 additions and 8 deletions

View file

@ -17,10 +17,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Security
## [2.0.1] - 2021-03-11
## [2.0.1] - 2021-05-27
### Added
- [2021-05-27] Added SNI check to prevent people from simply scanning nodes [@carbotaniuman].
### Changed
- [2021-05-21] Update metrics and fix cache directory leak [@carbotaniuman].
- [2021-05-21] Change headers to be wildcards [@carbotaniuman].
- [2021-05-27] Make sending the `Server` header configurable but off by default [@carbotaniuman].
## [2.0.0] - 2021-03-11
### Changed
@ -393,6 +397,7 @@ This release contains many breaking changes! Of note are the changes to the cach
- [2020-06-11] Tweaked logging configuration to reduce log file sizes by [@carbotaniuman].
[Unreleased]: https://gitlab.com/mangadex/mangadex_at_home/-/compare/2.0.0...HEAD
[2.0.1]: https://gitlab.com/mangadex/mangadex_at_home/-/compare/2.0.0...2.0.1
[2.0.0]: https://gitlab.com/mangadex/mangadex_at_home/-/compare/2.0.0-rc14...2.0.0
[2.0.0-rc14]: https://gitlab.com/mangadex/mangadex_at_home/-/compare/2.0.0-rc13...2.0.0-rc14
[2.0.0-rc13]: https://gitlab.com/mangadex/mangadex_at_home/-/compare/2.0.0-rc12...2.0.0-rc13

View file

@ -264,6 +264,7 @@ class ServerManager(
storage,
remoteSettings,
settings.serverSettings,
settings.devSettings,
settings.metricsSettings,
statistics,
registry,

View file

@ -30,6 +30,8 @@ import io.netty.handler.codec.DecoderException
import io.netty.handler.codec.http.HttpObjectAggregator
import io.netty.handler.codec.http.HttpServerCodec
import io.netty.handler.codec.http.HttpServerKeepAliveHandler
import io.netty.handler.ssl.SniCompletionEvent
import io.netty.handler.ssl.SniHandler
import io.netty.handler.ssl.SslContextBuilder
import io.netty.handler.stream.ChunkedWriteHandler
import io.netty.handler.timeout.ReadTimeoutException
@ -41,6 +43,7 @@ import io.netty.handler.traffic.TrafficCounter
import io.netty.incubator.channel.uring.IOUring
import io.netty.incubator.channel.uring.IOUringEventLoopGroup
import io.netty.incubator.channel.uring.IOUringServerSocketChannel
import io.netty.util.DomainWildcardMappingBuilder
import io.netty.util.concurrent.DefaultEventExecutorGroup
import io.netty.util.internal.SystemPropertyUtil
import mdnet.Constants
@ -48,6 +51,7 @@ import mdnet.data.Statistics
import mdnet.logging.info
import mdnet.logging.trace
import mdnet.logging.warn
import mdnet.settings.DevSettings
import mdnet.settings.ServerSettings
import mdnet.settings.TlsCert
import org.http4k.core.HttpHandler
@ -138,6 +142,7 @@ sealed class NettyTransport(threads: Int) {
class Netty(
private val tls: TlsCert,
private val serverSettings: ServerSettings,
private val devSettings: DevSettings,
private val statistics: Statistics
) : ServerConfig {
override fun toServer(http: HttpHandler): Http4kServer = object : Http4kServer {
@ -167,7 +172,29 @@ class Netty(
.channelFactory(transport.factory)
.childHandler(object : ChannelInitializer<SocketChannel>() {
public override fun initChannel(ch: SocketChannel) {
ch.pipeline().addLast("ssl", sslContext.newHandler(ch.alloc()))
ch.pipeline().addLast(
"ssl",
SniHandler(DomainWildcardMappingBuilder(sslContext).build())
)
ch.pipeline().addLast(
"dropHostname",
object : ChannelInboundHandlerAdapter() {
override fun userEventTriggered(ctx: ChannelHandlerContext, evt: Any) {
if (evt is SniCompletionEvent) {
if (!devSettings.disableSniCheck) {
if (!evt.hostname().endsWith("mangadex.network") &&
!evt.hostname().endsWith("localhost")
) {
ctx.close()
}
}
} else {
ctx.fireUserEventTriggered(evt)
}
}
}
)
ch.pipeline().addLast("codec", HttpServerCodec())
ch.pipeline().addLast("keepAlive", HttpServerKeepAliveHandler())

View file

@ -31,6 +31,7 @@ import mdnet.logging.warn
import mdnet.metrics.GeoIpMetricsFilterBuilder
import mdnet.metrics.PostTransactionLabeler
import mdnet.netty.Netty
import mdnet.settings.DevSettings
import mdnet.settings.MetricsSettings
import mdnet.settings.RemoteSettings
import mdnet.settings.ServerSettings
@ -46,6 +47,7 @@ fun getServer(
storage: ImageStorage,
remoteSettings: RemoteSettings,
serverSettings: ServerSettings,
devSettings: DevSettings,
metricsSettings: MetricsSettings,
statistics: Statistics,
registry: PrometheusMeterRegistry,
@ -109,7 +111,7 @@ fun getServer(
)
return timeRequest()
.then(addCommonHeaders())
.then(addCommonHeaders(devSettings.sendServerHeader))
.then(catchAllHideDetails())
.then(
routes(
@ -142,7 +144,7 @@ fun getServer(
GeoIpMetricsFilterBuilder(metricsSettings.enableGeoip, metricsSettings.geoipLicenseKey, registry).build()
)
)
.asServer(Netty(remoteSettings.tls!!, serverSettings, statistics))
.asServer(Netty(remoteSettings.tls!!, serverSettings, devSettings, statistics))
}
private val LOGGER = LoggerFactory.getLogger(ImageServer::class.java)

View file

@ -35,12 +35,17 @@ import java.util.*
private val HTTP_TIME_FORMATTER = DateTimeFormatter.ofPattern("EEE, dd MMM yyyy HH:mm:ss O", Locale.ENGLISH)
private val LOGGER = LoggerFactory.getLogger("Application")
fun addCommonHeaders(): Filter {
fun addCommonHeaders(sendServerHeader: Boolean): Filter {
return Filter { next: HttpHandler ->
{ request: Request ->
val response = next(request)
response.header("Date", HTTP_TIME_FORMATTER.format(ZonedDateTime.now(ZoneOffset.UTC)))
.header("Server", "MangaDex@Home Node ${BuildInfo.VERSION} (${Constants.CLIENT_BUILD})")
response.header("Date", HTTP_TIME_FORMATTER.format(ZonedDateTime.now(ZoneOffset.UTC))).let {
if (sendServerHeader) {
it.header("Server", "MangaDex@Home Node ${BuildInfo.VERSION} (${Constants.CLIENT_BUILD})")
} else {
it
}
}
}
}
}

View file

@ -47,7 +47,9 @@ data class ServerSettings(
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)
data class DevSettings(
val devUrl: String? = null
val devUrl: String? = null,
val disableSniCheck: Boolean = false,
val sendServerHeader: Boolean = false,
)
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy::class)

View file

@ -39,6 +39,7 @@ import org.http4k.core.Response
import org.http4k.core.Status
import org.http4k.kotest.shouldHaveHeader
import org.http4k.kotest.shouldHaveStatus
import org.http4k.kotest.shouldNotHaveHeader
import org.http4k.routing.bind
import org.http4k.routing.routes
import org.ktorm.database.Database
@ -106,6 +107,12 @@ class ImageServerTest : FreeSpec() {
response.close()
}
}
"should not have Server header" {
val response = handler(Request(Method.GET, "/data/02181a8f5fe8cd408720a771dd129fd8/T2.png"))
response.shouldNotHaveHeader("Server")
response.close()
}
}
"with real cache" - {