Skip to content

Commit

Permalink
HPCCC-33260 Allow a BM DFS service+dafilesrv to be secured
Browse files Browse the repository at this point in the history
1) Ensure BM DFS meta is remapped to point to the BM dafilesrv
and correct secure port.
2) Allow dafilesrv to be configured with a CA/certs/trusted peers,
so that it can be configured to only accepts connections from
trusted clients.

Signed-off-by: Jake Smith <[email protected]>
  • Loading branch information
jakesmith committed Jan 16, 2025
1 parent 3612b8a commit f350b6d
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 18 deletions.
9 changes: 8 additions & 1 deletion dali/base/dautils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3675,6 +3675,13 @@ static CConfigUpdateHook directIOUpdateHook;
static CriticalSection dafileSrvNodeCS;
static Owned<INode> tlsDirectIONode, nonTlsDirectIONode;

#ifndef _CONTAINERIZED
unsigned getBareMetalDaFsServerPort()
{
return getPreferredDafsClientPort(true);
}
#endif

void remapGroupsToDafilesrv(IPropertyTree *file, bool foreign, bool secure)
{
Owned<IPropertyTreeIterator> iter = file->getElements("Cluster");
Expand All @@ -3683,7 +3690,7 @@ void remapGroupsToDafilesrv(IPropertyTree *file, bool foreign, bool secure)
IPropertyTree &cluster = iter->query();
const char *planeName = cluster.queryProp("@name");
Owned<IStoragePlane> plane = getDataStoragePlane(planeName, true);
if ((0 == plane->queryHosts().size()) && isAbsolutePath(plane->queryPrefix())) // if hosts group, or url, don't touch
if (isAbsolutePath(plane->queryPrefix())) // if url (i.e. not absolute prefix path) don't touch
{
if (isContainerized())
{
Expand Down
4 changes: 3 additions & 1 deletion dali/base/dautils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -583,7 +583,9 @@ inline unsigned calcStripeNumber(unsigned partNum, const char *lfnName, unsigned
}
interface INamedGroupStore;
extern da_decl void remapGroupsToDafilesrv(IPropertyTree *file, bool foreign, bool secure);

#ifndef _CONTAINERIZED
unsigned getBareMetalDaFsServerPort();
#endif
#ifdef NULL_DALIUSER_STACKTRACE
extern da_decl void logNullUser(IUserDescriptor *userDesc);
#else
Expand Down
29 changes: 27 additions & 2 deletions esp/services/ws_dfsservice/ws_dfsservice.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,24 @@ static void populateLFNMeta(IUserDescriptor *userDesc, const char *logicalName,
{
VStringBuffer storagePlaneXPath("storage/%s", planeXPath.str());
Owned<IPropertyTree> dataPlane = getGlobalConfigSP()->getPropTree(storagePlaneXPath);

const char *hostGroupName = dataPlane->queryProp("@hostGroup");
if (!isEmptyString(hostGroupName))
{
Owned<IPropertyTree> hostGroup = getHostGroup(hostGroupName, false);
if (hostGroup)
{
dataPlane.setown(createPTreeFromIPT(dataPlane));
unsigned daFsSrvPort = getBareMetalDaFsServerPort();
Owned<IPropertyTreeIterator> iter = hostGroup->getElements("hosts");
ForEach(*iter)
{
VStringBuffer endpoint("%s:%u", iter->query().queryProp(nullptr), daFsSrvPort);
dataPlane->addProp("hosts", endpoint);
}
dataPlane->removeProp("@hostGroup");
}
}
metaRoot->addPropTree("planes", dataPlane.getClear());
}
}
Expand All @@ -135,6 +153,8 @@ static void populateLFNMeta(IUserDescriptor *userDesc, const char *logicalName,
void CWsDfsEx::init(IPropertyTree *cfg, const char *process, const char *service)
{
DBGLOG("Initializing %s service [process = %s]", service, process);
VStringBuffer xpath("Software/EspProcess/EspBinding[@service=\"%s\"]/@protocol", service);
isHttps = strsame("https", cfg->queryProp(xpath));
}

bool CWsDfsEx::onGetLease(IEspContext &context, IEspLeaseRequest &req, IEspLeaseResponse &resp)
Expand Down Expand Up @@ -177,8 +197,13 @@ bool CWsDfsEx::onDFSFileLookup(IEspContext &context, IEspDFSFileLookupRequest &r
if (req.getAccessViaDafilesrv())
opts |= LfnMOptRemap;

// NB: if we ever have some services with tls, and some without in bare-metal, this may need revisiting.
if (getComponentConfigSP()->getPropBool("@tls"))
if (isContainerized())
{
// NB: if we ever have some services with tls, and some without in bare-metal, this may need revisiting.
if (getComponentConfigSP()->getPropBool("@tls"))
opts |= LfnMOptTls;
}
else if (isHttps)
opts |= LfnMOptTls;

Owned<IPropertyTree> responseTree = createPTree();
Expand Down
1 change: 1 addition & 0 deletions esp/services/ws_dfsservice/ws_dfsservice.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

class CWsDfsEx : public CWsDfs
{
bool isHttps = false;
public:
virtual ~CWsDfsEx() {}
virtual void init(IPropertyTree *cfg, const char *process, const char *service);
Expand Down
9 changes: 9 additions & 0 deletions fs/dafilesrv/dafilesrv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,6 +590,15 @@ int main(int argc, const char* argv[])
if (componentExpert)
synchronizePTree(expert, componentExpert, false, true);

// merge in bare-metal dafilesrv component cert settings into newConfig
IPropertyTree *componentCert = nullptr;
componentCert = daFileSrv->queryPropTree("cert");
if (componentCert)
{
IPropertyTree *cert = ensurePTree(newConfig, "cert");
synchronizePTree(cert, componentCert, false, true);
}

// any overrides by Instance definitions?
Owned<IPropertyTreeIterator> iter = daFileSrv->getElements("Instance");
ForEach(*iter)
Expand Down
38 changes: 24 additions & 14 deletions fs/dafsserver/dafsserver.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,21 +132,31 @@ static ISecureSocket *createSecureSocket(ISocket *sock, bool disableClientCertVe
CriticalBlock b(secureContextCrit);
if (!secureContextServer)
{
#ifdef _CONTAINERIZED
/* Connections are expected from 3rd parties via TLS,
* we do not expect them to provide a valid certificate for verification.
* Currently the server (this dafilesrv), will use either the "public" certificate issuer,
* unless it's visibility is "cluster" (meaning internal only)
*/
if (isContainerized())
{
/* Connections are expected from 3rd parties via TLS,
* we do not expect them to provide a valid certificate for verification.
* Currently the server (this dafilesrv), will use either the "public" certificate issuer,
* unless it's visibility is "cluster" (meaning internal only)
*/

const char *certScope = strsame("cluster", getComponentConfigSP()->queryProp("service/@visibility")) ? "local" : "public";
Owned<const ISyncedPropertyTree> info = getIssuerTlsSyncedConfig(certScope, nullptr, disableClientCertVerification);
if (!info || !info->isValid())
throw makeStringException(-1, "createSecureSocket() : missing MTLS configuration");
secureContextServer.setown(createSecureSocketContextSynced(info, ServerSocket));
#else
secureContextServer.setown(createSecureSocketContextEx2(securitySettings.getSecureConfig(), ServerSocket));
#endif
const char *certScope = strsame("cluster", getComponentConfigSP()->queryProp("service/@visibility")) ? "local" : "public";
Owned<const ISyncedPropertyTree> info = getIssuerTlsSyncedConfig(certScope, nullptr, disableClientCertVerification);
if (!info || !info->isValid())
throw makeStringException(-1, "createSecureSocket() : missing MTLS configuration");
secureContextServer.setown(createSecureSocketContextSynced(info, ServerSocket));
}
else
{
IPropertyTree *cert = getComponentConfigSP()->getPropTree("cert");
if (cert)
{
Owned<ISyncedPropertyTree> certSyncedWrapper = createSyncedPropertyTree(cert);
secureContextServer.setown(createSecureSocketContextSynced(certSyncedWrapper, ServerSocket));
}
else
secureContextServer.setown(createSecureSocketContextEx2(securitySettings.getSecureConfig(), ServerSocket));
}
}
}
int loglevel = SSLogNormal;
Expand Down

0 comments on commit f350b6d

Please sign in to comment.