Allow for disabling https for proxied domains
This commit is contained in:
parent
7a1a2297d4
commit
dcbf45ec85
66
README.md
66
README.md
@ -79,6 +79,36 @@ domain:
|
|||||||
# domain list, but will not be configurable in the web interface
|
# domain list, but will not be configurable in the web interface
|
||||||
#public: false
|
#public: false
|
||||||
|
|
||||||
|
#proxied:
|
||||||
|
|
||||||
|
# An example built-in domain backed by an gemini and HTTP reverse-proxies to
|
||||||
|
# other backends.
|
||||||
|
#
|
||||||
|
# HTTP requests will be proxied to http_url, and gemini requests will be
|
||||||
|
# proxied to gemini_url. Either can be null.
|
||||||
|
#
|
||||||
|
# HTTP requests to the backing service will automatically have
|
||||||
|
# X-Forwarded-For and (if HTTPS) X-Forwarded-Proto headers added to them.
|
||||||
|
#
|
||||||
|
# Proxies are currently limited in the following ways:
|
||||||
|
# * http_url must be to an http endpoint (not https)
|
||||||
|
# * dns.resolver_addr is ignored and the system-wide dns is used
|
||||||
|
#
|
||||||
|
#example.com:
|
||||||
|
|
||||||
|
#http_url: "http://some.other.service.com"
|
||||||
|
#gemini_url: "gemini://some.other.service.com"
|
||||||
|
|
||||||
|
# Extra headers to add to proxied requests
|
||||||
|
#http_request_headers:
|
||||||
|
# - name: Host
|
||||||
|
# value: "yet.another.service.com"
|
||||||
|
# - name: X-HEADER-TO-DELETE
|
||||||
|
# value: ""
|
||||||
|
|
||||||
|
# Set to true to prevent the domain from being served over https.
|
||||||
|
#https_disabled: false
|
||||||
|
|
||||||
service:
|
service:
|
||||||
|
|
||||||
# Passphrase which must be given by users who are configuring new domains via
|
# Passphrase which must be given by users who are configuring new domains via
|
||||||
@ -91,7 +121,7 @@ service:
|
|||||||
#
|
#
|
||||||
# A CNAME record with the interface_domain of this server is automatically
|
# A CNAME record with the interface_domain of this server is automatically
|
||||||
# included, if it's not null itself.
|
# included, if it's not null itself.
|
||||||
dns_records:
|
#dns_records:
|
||||||
#- kind: A
|
#- kind: A
|
||||||
# addr: 127.0.0.1
|
# addr: 127.0.0.1
|
||||||
|
|
||||||
@ -119,45 +149,11 @@ service:
|
|||||||
# enabled. You can enable HTTPS by setting this to "[::]:443".
|
# enabled. You can enable HTTPS by setting this to "[::]:443".
|
||||||
#https_addr: null
|
#https_addr: null
|
||||||
|
|
||||||
#proxied_domains:
|
|
||||||
|
|
||||||
# An example built-in domain backed by an HTTP reverse-proxy to some
|
|
||||||
# other web-service. Requests to the backing service will automatically
|
|
||||||
# have X-Forwarded-For and (if HTTPS) X-Forwarded-Proto headers added to
|
|
||||||
# them.
|
|
||||||
#
|
|
||||||
# Proxies are currently limited in the following ways:
|
|
||||||
# * url must be to an http endpoint (not https)
|
|
||||||
# * dns.resolver_addr is ignored and the system-wide dns is used
|
|
||||||
#
|
|
||||||
#proxy.example.com:
|
|
||||||
# url: "http://some.other.service.com"
|
|
||||||
#
|
|
||||||
# # Extra headers to add to proxied requests
|
|
||||||
# request_headers:
|
|
||||||
# - name: Host
|
|
||||||
# value: "yet.another.service.com"
|
|
||||||
# - name: X-HEADER-TO-DELETE
|
|
||||||
# value: ""
|
|
||||||
|
|
||||||
#gemini:
|
#gemini:
|
||||||
|
|
||||||
# The address to listen for gemini requests on. Set this to null to disable
|
# The address to listen for gemini requests on. Set this to null to disable
|
||||||
# gemini support.
|
# gemini support.
|
||||||
#gemini_addr: "[::]:3965"
|
#gemini_addr: "[::]:3965"
|
||||||
|
|
||||||
#proxied_domains:
|
|
||||||
|
|
||||||
# An example built-in domain backed by a reverse-proxy to some other
|
|
||||||
# gemini server. Requests to this domain will have connections
|
|
||||||
# transparently proxied to the backing server.
|
|
||||||
#
|
|
||||||
# Proxies are currently limited in the following ways:
|
|
||||||
# * url must be to a gemini endpoint
|
|
||||||
# * dns.resolver_addr is ignored and the system-wide dns is used
|
|
||||||
#
|
|
||||||
#proxy.example.com:
|
|
||||||
# url: "gemini://some.other.service.com"
|
|
||||||
```
|
```
|
||||||
|
|
||||||
The YAML config file can be passed to the Domani process via the `--config-path`
|
The YAML config file can be passed to the Domani process via the `--config-path`
|
||||||
|
@ -40,17 +40,18 @@ pub struct ConfigBuiltinDomain {
|
|||||||
#[serde_as]
|
#[serde_as]
|
||||||
#[derive(Clone, Deserialize, Serialize)]
|
#[derive(Clone, Deserialize, Serialize)]
|
||||||
pub struct ConfigProxiedDomain {
|
pub struct ConfigProxiedDomain {
|
||||||
#[serde(default)]
|
|
||||||
#[serde_as(as = "Option<TryFromInto<String>>")]
|
#[serde_as(as = "Option<TryFromInto<String>>")]
|
||||||
pub gemini_url: Option<proxied_domain::GeminiUrl>,
|
pub gemini_url: Option<proxied_domain::GeminiUrl>,
|
||||||
|
|
||||||
#[serde(default)]
|
|
||||||
#[serde_as(as = "Option<TryFromInto<String>>")]
|
#[serde_as(as = "Option<TryFromInto<String>>")]
|
||||||
pub http_url: Option<proxied_domain::HttpUrl>,
|
pub http_url: Option<proxied_domain::HttpUrl>,
|
||||||
|
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
#[serde_as(as = "TryFromInto<Vec<proxied_domain::HttpRequestHeader>>")]
|
#[serde_as(as = "TryFromInto<Vec<proxied_domain::HttpRequestHeader>>")]
|
||||||
pub http_request_headers: proxied_domain::HttpRequestHeaders,
|
pub http_request_headers: proxied_domain::HttpRequestHeaders,
|
||||||
|
|
||||||
|
#[serde(default)]
|
||||||
|
pub https_disabled: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Deserialize, Serialize)]
|
||||||
|
@ -187,7 +187,7 @@ impl ManagerImpl {
|
|||||||
task_stack.push_spawn(|canceller| {
|
task_stack.push_spawn(|canceller| {
|
||||||
let manager = manager.clone();
|
let manager = manager.clone();
|
||||||
async move {
|
async move {
|
||||||
manager.sync_all_domains(canceller).await;
|
manager.sync_all_domains_job(canceller).await;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -204,7 +204,7 @@ impl ManagerImpl {
|
|||||||
self.origin_store.sync(origin_descr)
|
self.origin_store.sync(origin_descr)
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_domain_certs(&self, domain: &domain::Name) -> unexpected::Result<()> {
|
fn sync_domain_gemini_cert(&self, domain: &domain::Name) -> unexpected::Result<()> {
|
||||||
if let Some(ref gemini_store) = self.gemini_store {
|
if let Some(ref gemini_store) = self.gemini_store {
|
||||||
log::info!("Syncing gemini certificate for domain {domain}");
|
log::info!("Syncing gemini certificate for domain {domain}");
|
||||||
if let Some(_) = gemini_store.get_certificate(domain).or_unexpected()? {
|
if let Some(_) = gemini_store.get_certificate(domain).or_unexpected()? {
|
||||||
@ -218,7 +218,10 @@ impl ManagerImpl {
|
|||||||
|
|
||||||
gemini_store.set_certificate(domain, pkey, cert)?;
|
gemini_store.set_certificate(domain, pkey, cert)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn sync_domain_https_cert(&self, domain: &domain::Name) -> unexpected::Result<()> {
|
||||||
if let Some(ref acme_manager) = self.acme_manager {
|
if let Some(ref acme_manager) = self.acme_manager {
|
||||||
log::info!("Syncing HTTPS certificate for domain {domain}");
|
log::info!("Syncing HTTPS certificate for domain {domain}");
|
||||||
acme_manager.sync_domain(domain.clone()).await?;
|
acme_manager.sync_domain(domain.clone()).await?;
|
||||||
@ -227,20 +230,23 @@ impl ManagerImpl {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_all_domains_once(&self) -> unexpected::Result<()> {
|
async fn sync_all_domains(&self) -> unexpected::Result<()> {
|
||||||
let domains = self
|
let domains = self
|
||||||
.all_domains()
|
.all_domains()
|
||||||
.or_unexpected_while("fetching all domains")?
|
.or_unexpected_while("fetching all domains")?
|
||||||
.into_iter();
|
.into_iter();
|
||||||
|
|
||||||
for ManagedDomain { domain, .. } in domains {
|
for ManagedDomain { domain, .. } in domains {
|
||||||
let settings = match self
|
let (settings, https_cert, gemini_cert) = match self
|
||||||
.get_settings(&domain)
|
.get_settings(&domain)
|
||||||
.map_unexpected_while(|| format!("fetching settings for {domain}"))?
|
.map_unexpected_while(|| format!("fetching settings for {domain}"))?
|
||||||
{
|
{
|
||||||
GetSettingsResult::Stored(settings) => Some(settings),
|
GetSettingsResult::Stored(settings) => (Some(settings), true, true),
|
||||||
GetSettingsResult::Builtin(config) => Some(config.settings),
|
GetSettingsResult::Builtin(config) => (Some(config.settings), true, true),
|
||||||
GetSettingsResult::Proxied(_) => None,
|
|
||||||
|
// A proxied domain never needs gemini certs, since gemini requests will be
|
||||||
|
// transparently proxied to the backing server anyway.
|
||||||
|
GetSettingsResult::Proxied(config) => (None, !config.https_disabled, false),
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(settings) = settings {
|
if let Some(settings) = settings {
|
||||||
@ -253,20 +259,27 @@ impl ManagerImpl {
|
|||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
self.sync_domain_certs(&domain)
|
if gemini_cert {
|
||||||
.await
|
self.sync_domain_gemini_cert(&domain)
|
||||||
.map_unexpected_while(|| format!("syncing certs for domain {domain}",))?;
|
.map_unexpected_while(|| format!("syncing gemini cert for domain {domain}"))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
if https_cert {
|
||||||
|
self.sync_domain_https_cert(&domain)
|
||||||
|
.await
|
||||||
|
.map_unexpected_while(|| format!("syncing https cert for domain {domain}",))?;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn sync_all_domains(&self, canceller: CancellationToken) {
|
async fn sync_all_domains_job(&self, canceller: CancellationToken) {
|
||||||
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(20 * 60));
|
let mut interval = tokio::time::interval(tokio::time::Duration::from_secs(20 * 60));
|
||||||
loop {
|
loop {
|
||||||
tokio::select! {
|
tokio::select! {
|
||||||
_ = canceller.cancelled() => return,
|
_ = canceller.cancelled() => return,
|
||||||
_ = interval.tick() => if let Err(err) = self.sync_all_domains_once().await {
|
_ = interval.tick() => if let Err(err) = self.sync_all_domains().await {
|
||||||
log::error!("Failed to sync all domains: {err}")
|
log::error!("Failed to sync all domains: {err}")
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -326,10 +339,16 @@ impl Manager for ManagerImpl {
|
|||||||
.or_unexpected_while("calculating config hash")?;
|
.or_unexpected_while("calculating config hash")?;
|
||||||
|
|
||||||
self.domain_checker.check_domain(&domain, &hash).await?;
|
self.domain_checker.check_domain(&domain, &hash).await?;
|
||||||
|
|
||||||
self.sync_domain_origin(&domain, &settings.origin_descr)?;
|
self.sync_domain_origin(&domain, &settings.origin_descr)?;
|
||||||
self.sync_domain_certs(&domain)
|
|
||||||
|
self.sync_domain_gemini_cert(&domain)
|
||||||
|
.or_unexpected_while("syncing domain gemini cert")?;
|
||||||
|
|
||||||
|
self.sync_domain_https_cert(&domain)
|
||||||
.await
|
.await
|
||||||
.or_unexpected_while("syncing domain certs")?;
|
.or_unexpected_while("syncing domain https cert")?;
|
||||||
|
|
||||||
self.domain_store.set(&domain, &settings)?;
|
self.domain_store.set(&domain, &settings)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -473,6 +473,8 @@ impl Service {
|
|||||||
.as_str(),
|
.as_str(),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
return self.render_error_page(404, "Domain not found");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user