[release] v0.10.0-unstable16
This commit is contained in:
parent
a6b96bc42a
commit
9b033696e3
|
@ -66,6 +66,18 @@ function connect(file) {
|
|||
}))
|
||||
}
|
||||
|
||||
function block(nickname, devicename, block) {
|
||||
return wrap(fetch(`/cosmos/api/constellation/block`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json'
|
||||
},
|
||||
body: JSON.stringify({
|
||||
nickname, devicename, block
|
||||
}),
|
||||
}))
|
||||
}
|
||||
|
||||
export {
|
||||
list,
|
||||
addDevice,
|
||||
|
@ -74,4 +86,5 @@ export {
|
|||
getLogs,
|
||||
reset,
|
||||
connect,
|
||||
block,
|
||||
};
|
|
@ -27,26 +27,33 @@ import { strengthColor, strengthIndicator } from '../../../utils/password-streng
|
|||
|
||||
import { EyeOutlined, EyeInvisibleOutlined } from '@ant-design/icons';
|
||||
|
||||
export const CosmosInputText = ({ name, style, multiline, type, placeholder, onChange, label, formik }) => {
|
||||
export const CosmosInputText = ({ name, style, value, errors, multiline, type, placeholder, onChange, label, formik }) => {
|
||||
return <Grid item xs={12}>
|
||||
<Stack spacing={1} style={style}>
|
||||
<InputLabel htmlFor={name}>{label}</InputLabel>
|
||||
{label && <InputLabel htmlFor={name}>{label}</InputLabel>}
|
||||
<OutlinedInput
|
||||
id={name}
|
||||
type={type ? type : 'text'}
|
||||
value={formik.values[name]}
|
||||
value={value || (formik && formik.values[name])}
|
||||
name={name}
|
||||
multiline={multiline}
|
||||
onBlur={formik.handleBlur}
|
||||
onBlur={(...ar) => {
|
||||
return formik && formik.handleBlur(...ar);
|
||||
}}
|
||||
onChange={(...ar) => {
|
||||
onChange && onChange(...ar);
|
||||
return formik.handleChange(...ar);
|
||||
return formik && formik.handleChange(...ar);
|
||||
}}
|
||||
placeholder={placeholder}
|
||||
fullWidth
|
||||
error={Boolean(formik.touched[name] && formik.errors[name])}
|
||||
error={Boolean(formik && formik.touched[name] && formik.errors[name])}
|
||||
/>
|
||||
{formik.touched[name] && formik.errors[name] && (
|
||||
{formik && formik.touched[name] && formik.errors[name] && (
|
||||
<FormHelperText error id="standard-weight-helper-text-name-login">
|
||||
{formik.errors[name]}
|
||||
</FormHelperText>
|
||||
)}
|
||||
{errors && (
|
||||
<FormHelperText error id="standard-weight-helper-text-name-login">
|
||||
{formik.errors[name]}
|
||||
</FormHelperText>
|
||||
|
|
174
client/src/pages/constellation/dns.jsx
Normal file
174
client/src/pages/constellation/dns.jsx
Normal file
|
@ -0,0 +1,174 @@
|
|||
import React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import * as API from "../../api";
|
||||
import AddDeviceModal from "./addDevice";
|
||||
import PrettyTableView from "../../components/tableView/prettyTableView";
|
||||
import { DeleteButton } from "../../components/delete";
|
||||
import { CloudOutlined, CloudServerOutlined, CompassOutlined, DesktopOutlined, LaptopOutlined, MobileOutlined, TabletOutlined } from "@ant-design/icons";
|
||||
import IsLoggedIn from "../../isLoggedIn";
|
||||
import { Alert, Button, CircularProgress, InputLabel, Stack } from "@mui/material";
|
||||
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText } from "../config/users/formShortcuts";
|
||||
import MainCard from "../../components/MainCard";
|
||||
import { Formik } from "formik";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import ApiModal from "../../components/apiModal";
|
||||
import { isDomain } from "../../utils/indexs";
|
||||
import ConfirmModal from "../../components/confirmModal";
|
||||
import UploadButtons from "../../components/fileUpload";
|
||||
|
||||
export const ConstellationDNS = () => {
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [config, setConfig] = useState(null);
|
||||
|
||||
const refreshConfig = async () => {
|
||||
let configAsync = await API.config.get();
|
||||
setConfig(configAsync.data);
|
||||
setIsAdmin(configAsync.isAdmin);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshConfig();
|
||||
}, []);
|
||||
|
||||
return <>
|
||||
<IsLoggedIn />
|
||||
{(config) ? <>
|
||||
<Stack spacing={2} style={{maxWidth: "1000px"}}>
|
||||
<div>
|
||||
<MainCard title={"Constellation Internal DNS"} content={config.constellationIP}>
|
||||
<Stack spacing={2}>
|
||||
|
||||
<Formik
|
||||
initialValues={{
|
||||
Enabled: config.ConstellationConfig.DNS,
|
||||
Port: config.ConstellationConfig.DNSPort,
|
||||
Fallback: config.ConstellationConfig.DNSFallback,
|
||||
DNSBlockBlacklist: config.ConstellationConfig.DNSBlockBlacklist,
|
||||
DNSAdditionalBlocklists: config.ConstellationConfig.DNSAdditionalBlocklists,
|
||||
CustomDNSEntries: config.ConstellationConfig.CustomDNSEntries,
|
||||
}}
|
||||
onSubmit={(values) => {
|
||||
let newConfig = { ...config };
|
||||
newConfig.ConstellationConfig.DNS = values.Enabled;
|
||||
newConfig.ConstellationConfig.DNSPort = values.Port;
|
||||
newConfig.ConstellationConfig.DNSFallback = values.Fallback;
|
||||
newConfig.ConstellationConfig.DNSBlockBlacklist = values.DNSBlockBlacklist;
|
||||
newConfig.ConstellationConfig.DNSAdditionalBlocklists = values.DNSAdditionalBlocklists;
|
||||
newConfig.ConstellationConfig.CustomDNSEntries = values.CustomDNSEntries;
|
||||
|
||||
return API.config.set(newConfig);
|
||||
}}
|
||||
>
|
||||
{(formik) => (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Stack spacing={2}>
|
||||
<CosmosCheckbox formik={formik} name="Enabled" label="Constellation DNS Server Enabled" />
|
||||
<CosmosInputText formik={formik} name="Port" label="DNS Port" />
|
||||
<CosmosInputText formik={formik} name="Fallback" label="DNS Fallback" placeholder={'8.8.8.8:53'} />
|
||||
|
||||
<CosmosFormDivider title={"DNS Blocklists"} />
|
||||
|
||||
<CosmosCheckbox formik={formik} name="DNSBlockBlacklist" label="Use Blacklists to block domains" />
|
||||
|
||||
<InputLabel>DNS Blocklist URLs</InputLabel>
|
||||
{formik.values.DNSAdditionalBlocklists.map((item, index) => (
|
||||
<Stack direction={"row"} spacing={2} key={`DNSAdditionalBlocklists${item}`} width={"100%"}>
|
||||
<DeleteButton onDelete={() => {
|
||||
formik.setFieldValue("DNSAdditionalBlocklists", [...formik.values.DNSAdditionalBlocklists.slice(0, index), ...formik.values.DNSAdditionalBlocklists.slice(index + 1)]);
|
||||
}} />
|
||||
<div style={{flexGrow: 1}}>
|
||||
<CosmosInputText
|
||||
value={item}
|
||||
name={`DNSAdditionalBlocklists${index}`}
|
||||
placeholder={'https://example.com/blocklist.txt'}
|
||||
onChange={(e) => {
|
||||
formik.setFieldValue("DNSAdditionalBlocklists", [...formik.values.DNSAdditionalBlocklists.slice(0, index), e.target.value, ...formik.values.DNSAdditionalBlocklists.slice(index + 1)]);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Stack>
|
||||
))}
|
||||
<Stack direction="row" spacing={2}>
|
||||
<Button variant="outlined" onClick={() => {
|
||||
formik.setFieldValue("DNSAdditionalBlocklists", [...formik.values.DNSAdditionalBlocklists, ""]);
|
||||
}}>Add</Button>
|
||||
<Button variant="outlined" onClick={() => {
|
||||
formik.setFieldValue("DNSAdditionalBlocklists", [
|
||||
"https://s3.amazonaws.com/lists.disconnect.me/simple_tracking.txt",
|
||||
"https://s3.amazonaws.com/lists.disconnect.me/simple_ad.txt",
|
||||
"https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts",
|
||||
"https://raw.githubusercontent.com/StevenBlack/hosts/master/alternates/fakenews-only/hosts"
|
||||
]);
|
||||
}}>Reset Default</Button>
|
||||
</Stack>
|
||||
|
||||
<CosmosFormDivider title={"DNS Custom Entries"} />
|
||||
|
||||
<InputLabel>DNS Custom Entries</InputLabel>
|
||||
{formik.values.CustomDNSEntries.map((item, index) => (
|
||||
<Stack direction={"row"} spacing={2} key={`CustomDNSEntries${item}`} width={"100%"}>
|
||||
<DeleteButton onDelete={() => {
|
||||
formik.setFieldValue("CustomDNSEntries", [...formik.values.CustomDNSEntries.slice(0, index), ...formik.values.CustomDNSEntries.slice(index + 1)]);
|
||||
}} />
|
||||
<div style={{flexGrow: 1}}>
|
||||
<CosmosInputText
|
||||
value={item.Key}
|
||||
name={`CustomDNSEntries${index}-key`}
|
||||
placeholder={'domain.com'}
|
||||
onChange={(e) => {
|
||||
const updatedCustomDNSEntries = [...formik.values.CustomDNSEntries];
|
||||
updatedCustomDNSEntries[index].Key = e.target.value;
|
||||
formik.setFieldValue("CustomDNSEntries", updatedCustomDNSEntries);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{flexGrow: 1}}>
|
||||
<CosmosInputText
|
||||
value={item.Value}
|
||||
name={`CustomDNSEntries${index}-value`}
|
||||
placeholder={'1213.123.123.123'}
|
||||
onChange={(e) => {
|
||||
const updatedCustomDNSEntries = [...formik.values.CustomDNSEntries];
|
||||
updatedCustomDNSEntries[index].Value = e.target.value;
|
||||
formik.setFieldValue("CustomDNSEntries", updatedCustomDNSEntries);
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</Stack>
|
||||
))}
|
||||
<Stack direction="row" spacing={2}>
|
||||
<Button variant="outlined" onClick={() => {
|
||||
formik.setFieldValue("CustomDNSEntries", [...formik.values.CustomDNSEntries, {
|
||||
Key: "",
|
||||
Value: "",
|
||||
Type: "A"
|
||||
}]);
|
||||
}}>Add</Button>
|
||||
<Button variant="outlined" onClick={() => {
|
||||
formik.setFieldValue("CustomDNSEntries", [
|
||||
]);
|
||||
}}>Reset</Button>
|
||||
</Stack>
|
||||
|
||||
<LoadingButton
|
||||
disableElevation
|
||||
loading={formik.isSubmitting}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Save
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
</Formik>
|
||||
</Stack>
|
||||
</MainCard>
|
||||
</div>
|
||||
</Stack>
|
||||
</> : <center>
|
||||
<CircularProgress color="inherit" size={20} />
|
||||
</center>}
|
||||
</>
|
||||
};
|
|
@ -1,199 +1,35 @@
|
|||
import React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import * as API from "../../api";
|
||||
import AddDeviceModal from "./addDevice";
|
||||
import PrettyTableView from "../../components/tableView/prettyTableView";
|
||||
import { DeleteButton } from "../../components/delete";
|
||||
import { CloudOutlined, CloudServerOutlined, CompassOutlined, DesktopOutlined, LaptopOutlined, MobileOutlined, TabletOutlined } from "@ant-design/icons";
|
||||
import IsLoggedIn from "../../isLoggedIn";
|
||||
import { Alert, Button, CircularProgress, Stack } from "@mui/material";
|
||||
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText } from "../config/users/formShortcuts";
|
||||
import MainCard from "../../components/MainCard";
|
||||
import { Formik } from "formik";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import ApiModal from "../../components/apiModal";
|
||||
import { isDomain } from "../../utils/indexs";
|
||||
import ConfirmModal from "../../components/confirmModal";
|
||||
import UploadButtons from "../../components/fileUpload";
|
||||
import * as React from 'react';
|
||||
import MainCard from '../../components/MainCard';
|
||||
import { Chip, Divider, Stack, useMediaQuery } from '@mui/material';
|
||||
import HostChip from '../../components/hostChip';
|
||||
import { RouteMode, RouteSecurity } from '../../components/routeComponents';
|
||||
import { getFaviconURL } from '../../utils/routes';
|
||||
import * as API from '../../api';
|
||||
import { CheckOutlined, ClockCircleOutlined, DashboardOutlined, DeleteOutlined, DownOutlined, LockOutlined, UpOutlined } from "@ant-design/icons";
|
||||
import IsLoggedIn from '../../isLoggedIn';
|
||||
import PrettyTabbedView from '../../components/tabbedView/tabbedView';
|
||||
|
||||
const getDefaultConstellationHostname = (config) => {
|
||||
// if domain is set, use it
|
||||
if(isDomain(config.HTTPConfig.Hostname)) {
|
||||
return "vpn." + config.HTTPConfig.Hostname;
|
||||
} else {
|
||||
return config.HTTPConfig.Hostname;
|
||||
}
|
||||
import { ConstellationVPN } from './vpn';
|
||||
import { ConstellationDNS } from './dns';
|
||||
|
||||
const ConstellationIndex = () => {
|
||||
return <div>
|
||||
<IsLoggedIn />
|
||||
|
||||
<PrettyTabbedView path="/cosmos-ui/constellation/:tab" tabs={[
|
||||
{
|
||||
title: 'VPN',
|
||||
children: <ConstellationVPN />,
|
||||
path: 'vpn'
|
||||
},
|
||||
{
|
||||
title: 'DNS',
|
||||
children: <ConstellationDNS />,
|
||||
path: 'dns'
|
||||
},
|
||||
]}/>
|
||||
|
||||
</div>;
|
||||
}
|
||||
|
||||
export const ConstellationIndex = () => {
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [config, setConfig] = useState(null);
|
||||
const [users, setUsers] = useState(null);
|
||||
const [devices, setDevices] = useState(null);
|
||||
|
||||
const refreshConfig = async () => {
|
||||
let configAsync = await API.config.get();
|
||||
setConfig(configAsync.data);
|
||||
setIsAdmin(configAsync.isAdmin);
|
||||
setDevices((await API.constellation.list()).data || []);
|
||||
setUsers((await API.users.list()).data || []);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshConfig();
|
||||
}, []);
|
||||
|
||||
const getIcon = (r) => {
|
||||
if (r.deviceName.toLowerCase().includes("mobile") || r.deviceName.toLowerCase().includes("phone")) {
|
||||
return <MobileOutlined />
|
||||
}
|
||||
else if (r.deviceName.toLowerCase().includes("laptop") || r.deviceName.toLowerCase().includes("computer")) {
|
||||
return <LaptopOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("desktop")) {
|
||||
return <DesktopOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("tablet")) {
|
||||
return <TabletOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("lighthouse") || r.deviceName.toLowerCase().includes("server")) {
|
||||
return <CompassOutlined />
|
||||
} else {
|
||||
return <CloudOutlined />
|
||||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
<IsLoggedIn />
|
||||
{(devices && config && users) ? <>
|
||||
<Stack spacing={2} style={{maxWidth: "1000px"}}>
|
||||
<div>
|
||||
<MainCard title={"Constellation Setup"} content={config.constellationIP}>
|
||||
<Stack spacing={2}>
|
||||
{config.ConstellationConfig.Enabled && config.ConstellationConfig.SlaveMode && <>
|
||||
<Alert severity="info">
|
||||
You are currently connected to an external constellation network. Use your main Cosmos server to manage your constellation network and devices.
|
||||
</Alert>
|
||||
</>}
|
||||
<Formik
|
||||
initialValues={{
|
||||
Enabled: config.ConstellationConfig.Enabled,
|
||||
IsRelay: config.ConstellationConfig.NebulaConfig.Relay.AMRelay,
|
||||
ConstellationHostname: (config.ConstellationConfig.ConstellationHostname && config.ConstellationConfig.ConstellationHostname != "") ? config.ConstellationConfig.ConstellationHostname :
|
||||
getDefaultConstellationHostname(config)
|
||||
}}
|
||||
onSubmit={(values) => {
|
||||
let newConfig = { ...config };
|
||||
newConfig.ConstellationConfig.Enabled = values.Enabled;
|
||||
newConfig.ConstellationConfig.NebulaConfig.Relay.AMRelay = values.IsRelay;
|
||||
newConfig.ConstellationConfig.ConstellationHostname = values.ConstellationHostname;
|
||||
return API.config.set(newConfig);
|
||||
}}
|
||||
>
|
||||
{(formik) => (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Stack spacing={2}>
|
||||
{formik.values.Enabled && <Stack spacing={2} direction="row">
|
||||
<Button
|
||||
disableElevation
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={async () => {
|
||||
await API.constellation.restart();
|
||||
}}
|
||||
>
|
||||
Restart VPN Service
|
||||
</Button>
|
||||
<ApiModal callback={API.constellation.getLogs} label={"Show VPN logs"} />
|
||||
<ApiModal callback={API.constellation.getConfig} label={"Show VPN Config"} />
|
||||
<ConfirmModal
|
||||
variant="outlined"
|
||||
color="warning"
|
||||
label={"Reset Network"}
|
||||
content={"This will completely reset the network, and disconnect all the clients. You will need to reconnect them. This cannot be undone."}
|
||||
callback={async () => {
|
||||
await API.constellation.reset();
|
||||
refreshConfig();
|
||||
}}
|
||||
/>
|
||||
</Stack>}
|
||||
<CosmosCheckbox formik={formik} name="Enabled" label="Constellation Enabled" />
|
||||
{config.ConstellationConfig.Enabled && !config.ConstellationConfig.SlaveMode && <>
|
||||
{formik.values.Enabled && <>
|
||||
<CosmosCheckbox formik={formik} name="IsRelay" label="Relay requests via this Node" />
|
||||
<Alert severity="info">This is your Constellation hostname, that you will use to connect. If you are using a domain name, this needs to be different from your server's hostname. Whatever the domain you choose, it is very important that you make sure there is a A entry in your domain DNS pointing to this server. <strong>If you change this value, you will need to reset your network and reconnect all the clients!</strong></Alert>
|
||||
<CosmosInputText formik={formik} name="ConstellationHostname" label="Constellation Hostname" />
|
||||
</>}
|
||||
</>}
|
||||
<UploadButtons
|
||||
accept=".yml,.yaml"
|
||||
label={"Upload Nebula Config"}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
OnChange={async (e) => {
|
||||
let file = e.target.files[0];
|
||||
await API.constellation.connect(file);
|
||||
refreshConfig();
|
||||
}}
|
||||
/>
|
||||
<LoadingButton
|
||||
disableElevation
|
||||
loading={formik.isSubmitting}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Save
|
||||
</LoadingButton>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
</Formik>
|
||||
</Stack>
|
||||
</MainCard>
|
||||
</div>
|
||||
{config.ConstellationConfig.Enabled && !config.ConstellationConfig.SlaveMode && <>
|
||||
<CosmosFormDivider title={"Devices"} />
|
||||
<PrettyTableView
|
||||
data={devices}
|
||||
getKey={(r) => r.deviceName}
|
||||
buttons={[
|
||||
<AddDeviceModal isAdmin={isAdmin} users={users} config={config} refreshConfig={refreshConfig} devices={devices} />,
|
||||
]}
|
||||
columns={[
|
||||
{
|
||||
title: '',
|
||||
field: getIcon,
|
||||
},
|
||||
{
|
||||
title: 'Device Name',
|
||||
field: (r) => <strong>{r.deviceName}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
field: (r) => <strong>{r.nickname}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: (r) => <strong>{r.isLighthouse ? "Lighthouse" : "Client"}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Constellation IP',
|
||||
screenMin: 'md',
|
||||
field: (r) => r.ip,
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
clickable: true,
|
||||
field: (r) => {
|
||||
return <DeleteButton onDelete={async () => {
|
||||
alert("caca")
|
||||
}}></DeleteButton>
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</>}
|
||||
</Stack>
|
||||
</> : <center>
|
||||
<CircularProgress color="inherit" size={20} />
|
||||
</center>}
|
||||
</>
|
||||
};
|
||||
export default ConstellationIndex;
|
205
client/src/pages/constellation/vpn.jsx
Normal file
205
client/src/pages/constellation/vpn.jsx
Normal file
|
@ -0,0 +1,205 @@
|
|||
import React from "react";
|
||||
import { useEffect, useState } from "react";
|
||||
import * as API from "../../api";
|
||||
import AddDeviceModal from "./addDevice";
|
||||
import PrettyTableView from "../../components/tableView/prettyTableView";
|
||||
import { DeleteButton } from "../../components/delete";
|
||||
import { CloudOutlined, CloudServerOutlined, CompassOutlined, DesktopOutlined, LaptopOutlined, MobileOutlined, TabletOutlined } from "@ant-design/icons";
|
||||
import IsLoggedIn from "../../isLoggedIn";
|
||||
import { Alert, Button, CircularProgress, Stack } from "@mui/material";
|
||||
import { CosmosCheckbox, CosmosFormDivider, CosmosInputText } from "../config/users/formShortcuts";
|
||||
import MainCard from "../../components/MainCard";
|
||||
import { Formik } from "formik";
|
||||
import { LoadingButton } from "@mui/lab";
|
||||
import ApiModal from "../../components/apiModal";
|
||||
import { isDomain } from "../../utils/indexs";
|
||||
import ConfirmModal from "../../components/confirmModal";
|
||||
import UploadButtons from "../../components/fileUpload";
|
||||
|
||||
const getDefaultConstellationHostname = (config) => {
|
||||
// if domain is set, use it
|
||||
if(isDomain(config.HTTPConfig.Hostname)) {
|
||||
return "vpn." + config.HTTPConfig.Hostname;
|
||||
} else {
|
||||
return config.HTTPConfig.Hostname;
|
||||
}
|
||||
}
|
||||
|
||||
export const ConstellationVPN = () => {
|
||||
const [isAdmin, setIsAdmin] = useState(false);
|
||||
const [config, setConfig] = useState(null);
|
||||
const [users, setUsers] = useState(null);
|
||||
const [devices, setDevices] = useState(null);
|
||||
|
||||
const refreshConfig = async () => {
|
||||
let configAsync = await API.config.get();
|
||||
setConfig(configAsync.data);
|
||||
setIsAdmin(configAsync.isAdmin);
|
||||
setDevices((await API.constellation.list()).data || []);
|
||||
setUsers((await API.users.list()).data || []);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
refreshConfig();
|
||||
}, []);
|
||||
|
||||
const getIcon = (r) => {
|
||||
if (r.deviceName.toLowerCase().includes("mobile") || r.deviceName.toLowerCase().includes("phone")) {
|
||||
return <MobileOutlined />
|
||||
}
|
||||
else if (r.deviceName.toLowerCase().includes("laptop") || r.deviceName.toLowerCase().includes("computer")) {
|
||||
return <LaptopOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("desktop")) {
|
||||
return <DesktopOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("tablet")) {
|
||||
return <TabletOutlined />
|
||||
} else if (r.deviceName.toLowerCase().includes("lighthouse") || r.deviceName.toLowerCase().includes("server")) {
|
||||
return <CompassOutlined />
|
||||
} else {
|
||||
return <CloudOutlined />
|
||||
}
|
||||
}
|
||||
|
||||
return <>
|
||||
<IsLoggedIn />
|
||||
{(devices && config && users) ? <>
|
||||
<Stack spacing={2} style={{maxWidth: "1000px"}}>
|
||||
<div>
|
||||
<MainCard title={"Constellation Setup"} content={config.constellationIP}>
|
||||
<Stack spacing={2}>
|
||||
{config.ConstellationConfig.Enabled && config.ConstellationConfig.SlaveMode && <>
|
||||
<Alert severity="info">
|
||||
You are currently connected to an external constellation network. Use your main Cosmos server to manage your constellation network and devices.
|
||||
</Alert>
|
||||
</>}
|
||||
<Formik
|
||||
initialValues={{
|
||||
Enabled: config.ConstellationConfig.Enabled,
|
||||
PrivateNode: config.ConstellationConfig.PrivateNode,
|
||||
IsRelay: config.ConstellationConfig.NebulaConfig.Relay.AMRelay,
|
||||
ConstellationHostname: (config.ConstellationConfig.ConstellationHostname && config.ConstellationConfig.ConstellationHostname != "") ? config.ConstellationConfig.ConstellationHostname :
|
||||
getDefaultConstellationHostname(config)
|
||||
}}
|
||||
onSubmit={(values) => {
|
||||
let newConfig = { ...config };
|
||||
newConfig.ConstellationConfig.Enabled = values.Enabled;
|
||||
newConfig.ConstellationConfig.PrivateNode = values.PrivateNode;
|
||||
newConfig.ConstellationConfig.NebulaConfig.Relay.AMRelay = values.IsRelay;
|
||||
newConfig.ConstellationConfig.ConstellationHostname = values.ConstellationHostname;
|
||||
return API.config.set(newConfig);
|
||||
}}
|
||||
>
|
||||
{(formik) => (
|
||||
<form onSubmit={formik.handleSubmit}>
|
||||
<Stack spacing={2}>
|
||||
{formik.values.Enabled && <Stack spacing={2} direction="row">
|
||||
<Button
|
||||
disableElevation
|
||||
variant="outlined"
|
||||
color="primary"
|
||||
onClick={async () => {
|
||||
await API.constellation.restart();
|
||||
}}
|
||||
>
|
||||
Restart VPN Service
|
||||
</Button>
|
||||
<ApiModal callback={API.constellation.getLogs} label={"Show VPN logs"} />
|
||||
<ApiModal callback={API.constellation.getConfig} label={"Show VPN Config"} />
|
||||
<ConfirmModal
|
||||
variant="outlined"
|
||||
color="warning"
|
||||
label={"Reset Network"}
|
||||
content={"This will completely reset the network, and disconnect all the clients. You will need to reconnect them. This cannot be undone."}
|
||||
callback={async () => {
|
||||
await API.constellation.reset();
|
||||
refreshConfig();
|
||||
}}
|
||||
/>
|
||||
</Stack>}
|
||||
<CosmosCheckbox formik={formik} name="Enabled" label="Constellation Enabled" />
|
||||
{config.ConstellationConfig.Enabled && !config.ConstellationConfig.SlaveMode && <>
|
||||
{formik.values.Enabled && <>
|
||||
<CosmosCheckbox formik={formik} name="IsRelay" label="Relay requests via this Node" />
|
||||
<CosmosCheckbox formik={formik} name="PrivateNode" label="This node is Private (no public IP)" />
|
||||
{!formik.values.PrivateNode && <>
|
||||
<Alert severity="info">This is your Constellation hostname, that you will use to connect. If you are using a domain name, this needs to be different from your server's hostname. Whatever the domain you choose, it is very important that you make sure there is a A entry in your domain DNS pointing to this server. <strong>If you change this value, you will need to reset your network and reconnect all the clients!</strong></Alert>
|
||||
<CosmosInputText formik={formik} name="ConstellationHostname" label="Constellation Hostname" />
|
||||
</>}
|
||||
</>}
|
||||
</>}
|
||||
<LoadingButton
|
||||
disableElevation
|
||||
loading={formik.isSubmitting}
|
||||
type="submit"
|
||||
variant="contained"
|
||||
color="primary"
|
||||
>
|
||||
Save
|
||||
</LoadingButton>
|
||||
<UploadButtons
|
||||
accept=".yml,.yaml"
|
||||
label={"Upload External Constellation Network File"}
|
||||
variant="outlined"
|
||||
fullWidth
|
||||
OnChange={async (e) => {
|
||||
let file = e.target.files[0];
|
||||
await API.constellation.connect(file);
|
||||
refreshConfig();
|
||||
}}
|
||||
/>
|
||||
</Stack>
|
||||
</form>
|
||||
)}
|
||||
</Formik>
|
||||
</Stack>
|
||||
</MainCard>
|
||||
</div>
|
||||
{config.ConstellationConfig.Enabled && !config.ConstellationConfig.SlaveMode && <>
|
||||
<CosmosFormDivider title={"Devices"} />
|
||||
<PrettyTableView
|
||||
data={devices.filter((d) => !d.blocked)}
|
||||
getKey={(r) => r.deviceName}
|
||||
buttons={[
|
||||
<AddDeviceModal isAdmin={isAdmin} users={users} config={config} refreshConfig={refreshConfig} devices={devices} />,
|
||||
]}
|
||||
columns={[
|
||||
{
|
||||
title: '',
|
||||
field: getIcon,
|
||||
},
|
||||
{
|
||||
title: 'Device Name',
|
||||
field: (r) => <strong>{r.deviceName}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Owner',
|
||||
field: (r) => <strong>{r.nickname}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Type',
|
||||
field: (r) => <strong>{r.isLighthouse ? "Lighthouse" : "Client"}</strong>,
|
||||
},
|
||||
{
|
||||
title: 'Constellation IP',
|
||||
screenMin: 'md',
|
||||
field: (r) => r.ip,
|
||||
},
|
||||
{
|
||||
title: '',
|
||||
clickable: true,
|
||||
field: (r) => {
|
||||
return <DeleteButton onDelete={async () => {
|
||||
await API.constellation.block(r.nickname, r.deviceName, true);
|
||||
refreshConfig();
|
||||
}}></DeleteButton>
|
||||
}
|
||||
}
|
||||
]}
|
||||
/>
|
||||
</>}
|
||||
</Stack>
|
||||
</> : <center>
|
||||
<CircularProgress color="inherit" size={20} />
|
||||
</center>}
|
||||
</>
|
||||
};
|
|
@ -15,7 +15,7 @@ import ContainerIndex from '../pages/servapps/containers';
|
|||
import NewDockerServiceForm from '../pages/servapps/containers/newServiceForm';
|
||||
import OpenIdList from '../pages/openid/openid-list';
|
||||
import MarketPage from '../pages/market/listing';
|
||||
import { ConstellationIndex } from '../pages/constellation';
|
||||
import ConstellationIndex from '../pages/constellation';
|
||||
|
||||
|
||||
// render - dashboard
|
||||
|
|
27
go.mod
27
go.mod
|
@ -8,7 +8,7 @@ require (
|
|||
github.com/docker/docker v23.0.3+incompatible
|
||||
github.com/docker/go-connections v0.4.0
|
||||
github.com/foomo/tlsconfig v0.0.0-20180418120404-b67861b076c9
|
||||
github.com/go-acme/lego/v4 v4.13.3
|
||||
github.com/go-acme/lego/v4 v4.14.2
|
||||
github.com/go-chi/chi v4.0.2+incompatible
|
||||
github.com/go-chi/httprate v0.7.1
|
||||
github.com/go-playground/validator/v10 v10.14.0
|
||||
|
@ -16,7 +16,9 @@ require (
|
|||
github.com/gorilla/mux v1.8.0
|
||||
github.com/gorilla/websocket v1.5.0
|
||||
github.com/jasonlvhit/gocron v0.0.1
|
||||
github.com/miekg/dns v1.1.55
|
||||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible
|
||||
github.com/ory/fosite v0.44.0
|
||||
github.com/oschwald/geoip2-golang v1.8.0
|
||||
github.com/pquerna/otp v1.4.0
|
||||
|
@ -27,6 +29,7 @@ require (
|
|||
golang.org/x/crypto v0.10.0
|
||||
golang.org/x/net v0.11.0
|
||||
golang.org/x/sys v0.9.0
|
||||
gopkg.in/yaml.v2 v2.4.0
|
||||
)
|
||||
|
||||
require (
|
||||
|
@ -57,7 +60,20 @@ require (
|
|||
github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 // indirect
|
||||
github.com/andybalholm/cascadia v1.1.0 // indirect
|
||||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 // indirect
|
||||
github.com/aws/aws-sdk-go v1.39.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2 v1.19.0 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.28 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.27.2 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.4 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 // indirect
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 // indirect
|
||||
github.com/aws/smithy-go v1.13.5 // indirect
|
||||
github.com/boombuler/barcode v1.0.1-0.20190219062509-6c824513bacc // indirect
|
||||
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
|
||||
github.com/cespare/xxhash/v2 v2.2.0 // indirect
|
||||
|
@ -126,7 +142,6 @@ require (
|
|||
github.com/magiconair/properties v1.8.4 // indirect
|
||||
github.com/mattn/go-isatty v0.0.19 // indirect
|
||||
github.com/mattn/goveralls v0.0.6 // indirect
|
||||
github.com/miekg/dns v1.1.55 // indirect
|
||||
github.com/mimuret/golang-iij-dpf v0.9.1 // indirect
|
||||
github.com/mitchellh/go-homedir v1.1.0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.5.0 // indirect
|
||||
|
@ -137,6 +152,7 @@ require (
|
|||
github.com/montanaflynn/stats v0.7.0 // indirect
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 // indirect
|
||||
github.com/nrdcg/auroradns v1.1.0 // indirect
|
||||
github.com/nrdcg/bunny-go v0.0.0-20230728143221-c9dda82568d9 // indirect
|
||||
github.com/nrdcg/desec v0.7.0 // indirect
|
||||
github.com/nrdcg/dnspod-go v0.4.0 // indirect
|
||||
github.com/nrdcg/freemyip v0.2.0 // indirect
|
||||
|
@ -153,7 +169,7 @@ require (
|
|||
github.com/ory/viper v1.7.5 // indirect
|
||||
github.com/ory/x v0.0.214 // indirect
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 // indirect
|
||||
github.com/ovh/go-ovh v1.4.1 // indirect
|
||||
github.com/ovh/go-ovh v1.4.2 // indirect
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible // indirect
|
||||
github.com/pborman/uuid v1.2.0 // indirect
|
||||
github.com/pelletier/go-toml v1.8.1 // indirect
|
||||
|
@ -167,7 +183,6 @@ require (
|
|||
github.com/sacloud/packages-go v0.0.9 // indirect
|
||||
github.com/scaleway/scaleway-sdk-go v1.0.0-beta.17 // indirect
|
||||
github.com/shoenig/go-m1cpu v0.1.6 // indirect
|
||||
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 // indirect
|
||||
github.com/sirupsen/logrus v1.8.1 // indirect
|
||||
github.com/smartystreets/go-aws-auth v0.0.0-20180515143844-0c1422d1fdb9 // indirect
|
||||
github.com/softlayer/softlayer-go v1.1.2 // indirect
|
||||
|
@ -210,9 +225,9 @@ require (
|
|||
google.golang.org/grpc v1.53.0 // indirect
|
||||
google.golang.org/protobuf v1.28.1 // indirect
|
||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 // indirect
|
||||
gopkg.in/ns1/ns1-go.v2 v2.7.6 // indirect
|
||||
gopkg.in/square/go-jose.v2 v2.6.0 // indirect
|
||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||
gotest.tools/v3 v3.4.0 // indirect
|
||||
)
|
||||
|
|
48
go.sum
48
go.sum
|
@ -60,6 +60,7 @@ github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBp
|
|||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0 h1:OBhqkivkhkMqLPymWEppkm7vgPQY2XsHoEkaMQ0AdZY=
|
||||
github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0/go.mod h1:kgDmCTgBzIEPFElEF+FK0SdjAor06dRq2Go927dnQ6o=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
|
||||
github.com/DataDog/datadog-go v4.0.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
|
||||
|
@ -107,9 +108,35 @@ github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535 h1:4daAzAu0
|
|||
github.com/asaskevich/govalidator v0.0.0-20200428143746-21a406dcc535/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
|
||||
github.com/aws/aws-sdk-go v1.23.19/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
|
||||
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
|
||||
github.com/aws/aws-sdk-go v1.39.0 h1:74BBwkEmiqBbi2CGflEh34l0YNtIibTjZsibGarkNjo=
|
||||
github.com/aws/aws-sdk-go v1.39.0/go.mod h1:hcU610XS61/+aQV88ixoOzUoG7v3b31pl2zKMmprdro=
|
||||
github.com/aws/aws-sdk-go-v2 v1.19.0 h1:klAT+y3pGFBU/qVf1uzwttpBbiuozJYWzNLHioyDJ+k=
|
||||
github.com/aws/aws-sdk-go-v2 v1.19.0/go.mod h1:uzbQtefpm44goOPmdKyAlXSNcwlRgF3ePWVW6EtJvvw=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.28 h1:TINEaKyh1Td64tqFvn09iYpKiWjmHYrG1fa91q2gnqw=
|
||||
github.com/aws/aws-sdk-go-v2/config v1.18.28/go.mod h1:nIL+4/8JdAuNHEjn/gPEXqtnS02Q3NXB/9Z7o5xE4+A=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.27 h1:dz0yr/yR1jweAnsCx+BmjerUILVPQ6FS5AwF/OyG1kA=
|
||||
github.com/aws/aws-sdk-go-v2/credentials v1.13.27/go.mod h1:syOqAek45ZXZp29HlnRS/BNgMIW6uiRmeuQsz4Qh2UE=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5 h1:kP3Me6Fy3vdi+9uHd7YLr6ewPxRL+PU6y15urfTaamU=
|
||||
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.13.5/go.mod h1:Gj7tm95r+QsDoN2Fhuz/3npQvcZbkEf5mL70n3Xfluc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35 h1:hMUCiE3Zi5AHrRNGf5j985u0WyqI6r2NULhUfo0N/No=
|
||||
github.com/aws/aws-sdk-go-v2/internal/configsources v1.1.35/go.mod h1:ipR5PvpSPqIqL5Mi82BxLnfMkHVbmco8kUwO2xrCi0M=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29 h1:yOpYx+FTBdpk/g+sBU6Cb1H0U/TLEcYYp66mYqsPpcc=
|
||||
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.4.29/go.mod h1:M/eUABlDbw2uVrdAn+UsI6M727qp2fxkp8K0ejcBDUY=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36 h1:8r5m1BoAWkn0TDC34lUculryf7nUF25EgIMdjvGCkgo=
|
||||
github.com/aws/aws-sdk-go-v2/internal/ini v1.3.36/go.mod h1:Rmw2M1hMVTwiUhjwMoIBFWFJMhvJbct06sSidxInkhY=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29 h1:IiDolu/eLmuB18DRZibj77n1hHQT7z12jnGO7Ze3pLc=
|
||||
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.29/go.mod h1:fDbkK4o7fpPXWn8YAPmTieAMuB9mk/VgvW64uaUqxd4=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.27.2 h1:PwNeYoonBzmTdCztKiiutws3U24KrnDBuabzRfIlZY4=
|
||||
github.com/aws/aws-sdk-go-v2/service/lightsail v1.27.2/go.mod h1:gQhLZrTEath4zik5ixIe6axvgY5jJrgSBDJ360Fxnco=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.4 h1:p4mTxJfCAyiTT4Wp6p/mOPa6j5MqCSRGot8qZwFs+Z0=
|
||||
github.com/aws/aws-sdk-go-v2/service/route53 v1.28.4/go.mod h1:VBLWpaHvhQNeu7N9rMEf00SWeOONb/HvaDUxe/7b44k=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13 h1:sWDv7cMITPcZ21QdreULwxOOAmE05JjEsT6fCDtDA9k=
|
||||
github.com/aws/aws-sdk-go-v2/service/sso v1.12.13/go.mod h1:DfX0sWuT46KpcqbMhJ9QWtxAIP1VozkDWf8VAkByjYY=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13 h1:BFubHS/xN5bjl818QaroN6mQdjneYQ+AOx44KNXlyH4=
|
||||
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.13/go.mod h1:BzqsVVFduubEmzrVtUFQQIQdFqvUItF8XUq2EnS8Wog=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3 h1:e5mnydVdCVWxP+5rPAGi2PYxC7u2OZgH1ypC114H04U=
|
||||
github.com/aws/aws-sdk-go-v2/service/sts v1.19.3/go.mod h1:yVGZA1CPkmUhBdA039jXNJJG7/6t+G+EBWmFq23xqnY=
|
||||
github.com/aws/aws-xray-sdk-go v0.9.4/go.mod h1:XtMKdBQfpVut+tJEwI7+dJFRxxRdxHDyVNp2tHXRq04=
|
||||
github.com/aws/smithy-go v1.13.5 h1:hgz0X/DX0dGqTYpGALqXJoRKRj5oQ7150i5FdTePzO8=
|
||||
github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA=
|
||||
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
|
||||
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
|
||||
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
|
||||
|
@ -259,8 +286,8 @@ github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm
|
|||
github.com/gin-gonic/gin v1.7.4/go.mod h1:jD2toBW3GZUr5UMcdrwQA10I7RuaFOl/SGeDjXkfUtY=
|
||||
github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
|
||||
github.com/go-acme/lego/v4 v4.13.3 h1:aZ1S9FXIkCWG3Uw/rZKSD+MOuO8ZB1t6p9VCg6jJiNY=
|
||||
github.com/go-acme/lego/v4 v4.13.3/go.mod h1:c/iodVGMeBXG/+KiQczoNkySo3YLWTVa0kiyeVd/FHc=
|
||||
github.com/go-acme/lego/v4 v4.14.2 h1:/D/jqRgLi8Cbk33sLGtu2pX2jEg3bGJWHyV8kFuUHGM=
|
||||
github.com/go-acme/lego/v4 v4.14.2/go.mod h1:kBXxbeTg0x9AgaOYjPSwIeJy3Y33zTz+tMD16O4MO6c=
|
||||
github.com/go-bindata/go-bindata v3.1.1+incompatible/go.mod h1:xK8Dsgwmeed+BBsSy2XTopBn/8uK2HWuGSnA11C3Joo=
|
||||
github.com/go-chi/chi v4.0.2+incompatible h1:maB6vn6FqCxrpz4FqWdh4+lwpyZIQS7YEAUcHlgXVRs=
|
||||
github.com/go-chi/chi v4.0.2+incompatible/go.mod h1:eB3wogJHnLi3x/kFX2A+IbTBlXxmMeXJVKy9tTv1XzQ=
|
||||
|
@ -672,6 +699,7 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
|
|||
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.7/go.mod h1:n+brtR0CgQNWTVd5ZUFpTBC8YFBDLK/h/bpaJ8/DtOE=
|
||||
github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
|
||||
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
|
||||
github.com/google/go-github/v32 v32.1.0/go.mod h1:rIEpZD9CTDQwDK9GDrtMTycQNA4JU3qBsCizh3q2WCI=
|
||||
|
@ -1024,11 +1052,15 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J
|
|||
github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw=
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04 h1:o6uBwrhM5C8Ll3MAAxrQxRHEu7FkapwTuI2WmL1rw4g=
|
||||
github.com/namedotcom/go v0.0.0-20180403034216-08470befbe04/go.mod h1:5sN+Lt1CaY4wsPvgQH/jsuJi4XO2ssZbdsIizr4CVC8=
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible h1:4QJd3OLAMgj7ph+yZTuX13Ld4UpgHp07nNdFX7mqFfM=
|
||||
github.com/natefinch/lumberjack v2.0.0+incompatible/go.mod h1:Wi9p2TTF5DG5oU+6YfsmYQpsTIOm0B1VNzQg9Mw6nPk=
|
||||
github.com/nbio/st v0.0.0-20140626010706-e9e8d9816f32/go.mod h1:9wM+0iRr9ahx58uYLpLIr5fm8diHn0JbqRycJi6w0Ms=
|
||||
github.com/nicksnyder/go-i18n v1.10.0/go.mod h1:HrK7VCrbOvQoUAQ7Vpy7i87N7JZZZ7R2xBGjv0j365Q=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/nrdcg/auroradns v1.1.0 h1:KekGh8kmf2MNwqZVVYo/fw/ZONt8QMEmbMFOeljteWo=
|
||||
github.com/nrdcg/auroradns v1.1.0/go.mod h1:O7tViUZbAcnykVnrGkXzIJTHoQCHcgalgAe6X1mzHfk=
|
||||
github.com/nrdcg/bunny-go v0.0.0-20230728143221-c9dda82568d9 h1:qpB3wZR4+MPK92cTC9zZPnndkJgDgPvQqPUAgVc1NXU=
|
||||
github.com/nrdcg/bunny-go v0.0.0-20230728143221-c9dda82568d9/go.mod h1:HUoHXDrFvidN1NK9Wb/mZKNOfDNutKkzF2Pg71M9hHA=
|
||||
github.com/nrdcg/desec v0.7.0 h1:iuGhi4pstF3+vJWwt292Oqe2+AsSPKDynQna/eu1fDs=
|
||||
github.com/nrdcg/desec v0.7.0/go.mod h1:e1uRqqKv1mJdd5+SQROAhmy75lKMphLzWIuASLkpeFY=
|
||||
github.com/nrdcg/dnspod-go v0.4.0 h1:c/jn1mLZNKF3/osJ6mz3QPxTudvPArXTjpkmYj0uK6U=
|
||||
|
@ -1124,8 +1156,8 @@ github.com/oschwald/geoip2-golang v1.8.0 h1:KfjYB8ojCEn/QLqsDU0AzrJ3R5Qa9vFlx3z6
|
|||
github.com/oschwald/geoip2-golang v1.8.0/go.mod h1:R7bRvYjOeaoenAp9sKRS8GX5bJWcZ0laWO5+DauEktw=
|
||||
github.com/oschwald/maxminddb-golang v1.10.0 h1:Xp1u0ZhqkSuopaKmk1WwHtjF0H9Hd9181uj2MQ5Vndg=
|
||||
github.com/oschwald/maxminddb-golang v1.10.0/go.mod h1:Y2ELenReaLAZ0b400URyGwvYxHV1dLIxBuyOsyYjHK0=
|
||||
github.com/ovh/go-ovh v1.4.1 h1:VBGa5wMyQtTP7Zb+w97zRCh9sLtM/2YKRyy+MEJmWaM=
|
||||
github.com/ovh/go-ovh v1.4.1/go.mod h1:6bL6pPyUT7tBfI0pqOegJgRjgjuO+mOo+MyXd1EEC0M=
|
||||
github.com/ovh/go-ovh v1.4.2 h1:ub4jVK6ERbiBTo4y5wbLCjeKCjGY+K36e7BviW+MaAU=
|
||||
github.com/ovh/go-ovh v1.4.2/go.mod h1:AkPXVtgwB6xlKblMjRKJJmjRp+ogrE7fz2lVgcQY8SY=
|
||||
github.com/parnurzeal/gorequest v0.2.15/go.mod h1:3Kh2QUMJoqw3icWAecsyzkpY7UzRfDhbRdTjtNwNiUE=
|
||||
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
|
||||
|
@ -1241,8 +1273,6 @@ github.com/shurcooL/highlight_go v0.0.0-20170515013102-78fb10f4a5f8/go.mod h1:UD
|
|||
github.com/shurcooL/octicon v0.0.0-20180602230221-c42b0e3b24d9/go.mod h1:eWdoE5JD4R5UVWDucdOPg1g2fqQRq78IQa9zlOV1vpQ=
|
||||
github.com/shurcooL/sanitized_anchor_name v0.0.0-20170918181015-86672fcb3f95/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
|
||||
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04 h1:ZTzdx88+AcnjqUfJwnz89UBrMSBQ1NEysg9u5d+dU9c=
|
||||
github.com/simplesurance/bunny-go v0.0.0-20221115111006-e11d9dc91f04/go.mod h1:5KS21fpch8TIMyAUv/qQqTa3GZfBDYgjaZbd2KXKYfg=
|
||||
github.com/sirupsen/logrus v1.0.4-0.20170822132746-89742aefa4b2/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.0.6/go.mod h1:pMByvHTf9Beacp5x1UXfOR9xyW/9antXMhjMPG0dEzc=
|
||||
github.com/sirupsen/logrus v1.1.0/go.mod h1:zrgwTnHtNr00buQ1vSptGe8m1f/BbgsPukg8qsT7A+A=
|
||||
|
@ -1877,6 +1907,8 @@ gopkg.in/ini.v1 v1.66.2/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
|||
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
|
||||
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
|
||||
gopkg.in/mail.v2 v2.0.0-20180731213649-a0242b2233b4/go.mod h1:htwXN1Qh09vZJ1NVKxQqHPBaCBbzKhp5GzuJEA4VJWw=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1 h1:bBRl1b0OH9s/DuPhuXpNl+VtCaJXFZ5/uEFST95x9zc=
|
||||
gopkg.in/natefinch/lumberjack.v2 v2.2.1/go.mod h1:YD8tP3GAjkrDg1eZH7EGmyESg/lsYskCTPBJVb9jqSc=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.7.6 h1:mCPl7q0jbIGACXvGBljAuuApmKZo3rRi4tlRIEbMvjA=
|
||||
gopkg.in/ns1/ns1-go.v2 v2.7.6/go.mod h1:GMnKY+ZuoJ+lVLL+78uSTjwTz2jMazq6AfGKQOYhsPk=
|
||||
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "cosmos-server",
|
||||
"version": "0.10.0-unstable15",
|
||||
"version": "0.10.0-unstable16",
|
||||
"description": "",
|
||||
"main": "test-server.js",
|
||||
"bugs": {
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<a href="https://github.com/soldier1"><img src="https://avatars.githubusercontent.com/soldier1" style="border-radius:48px" width="48" height="48" alt="null" title="null" /></a>
|
||||
<a href="https://github.com/devcircus"><img src="https://avatars.githubusercontent.com/devcircus" style="border-radius:48px" width="48" height="48" alt="Clayton Stone" title="Clayton Stone" /></a>
|
||||
<a href="https://github.com/BlackrazorNZ"><img src="https://avatars.githubusercontent.com/BlackrazorNZ" style="border-radius:48px" width="48" height="48" alt="null" title="null" /></a>
|
||||
<a href="https://github.com/bleibdirtroy"><img src="https://avatars.githubusercontent.com/bleibdirtroy" style="border-radius:48px" width="48" height="48" alt="Adrian Germeck" title="Adrian Germeck" /></a>
|
||||
<a href="https://github.com/bleibdirtroy"><img src="https://avatars.githubusercontent.com/bleibdirtroy" style="border-radius:48px" width="48" height="48" alt="Adrian" title="Adrian" /></a>
|
||||
</p><!-- /sponsors -->
|
||||
|
||||
---
|
||||
|
|
|
@ -46,7 +46,10 @@ func handleDNSRequest(w dns.ResponseWriter, r *dns.Msg) {
|
|||
|
||||
// Overwrite local hostnames with custom entries
|
||||
for _, q := range r.Question {
|
||||
for hostname, ip := range customDNSEntries {
|
||||
for _, entry := range customDNSEntries {
|
||||
hostname := entry.Key
|
||||
ip := entry.Value
|
||||
|
||||
if strings.HasSuffix(q.Name, hostname + ".") && q.Qtype == dns.TypeA {
|
||||
utils.Debug("DNS Overwrite " + hostname + " with " + ip)
|
||||
rr, _ := dns.NewRR(q.Name + " A " + ip)
|
||||
|
|
99
src/constellation/api_devices_block.go
Normal file
99
src/constellation/api_devices_block.go
Normal file
|
@ -0,0 +1,99 @@
|
|||
package constellation
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"encoding/json"
|
||||
|
||||
"github.com/azukaar/cosmos-server/src/utils"
|
||||
)
|
||||
|
||||
type DeviceBlockRequestJSON struct {
|
||||
Nickname string `json:"nickname",validate:"required,min=3,max=32,alphanum"`
|
||||
DeviceName string `json:"deviceName",validate:"required,min=3,max=32,alphanum"`
|
||||
Block bool `json:"block",omitempty`
|
||||
}
|
||||
|
||||
func DeviceBlock(w http.ResponseWriter, req *http.Request) {
|
||||
if(req.Method == "POST") {
|
||||
var request DeviceBlockRequestJSON
|
||||
err1 := json.NewDecoder(req.Body).Decode(&request)
|
||||
if err1 != nil {
|
||||
utils.Error("ConstellationDeviceBlocking: Invalid User Request", err1)
|
||||
utils.HTTPError(w, "Device Creation Error",
|
||||
http.StatusInternalServerError, "DB001")
|
||||
return
|
||||
}
|
||||
|
||||
errV := utils.Validate.Struct(request)
|
||||
if errV != nil {
|
||||
utils.Error("DeviceBlocking: Invalid User Request", errV)
|
||||
utils.HTTPError(w, "Device Creation Error: " + errV.Error(),
|
||||
http.StatusInternalServerError, "DB002")
|
||||
return
|
||||
}
|
||||
|
||||
nickname := utils.Sanitize(request.Nickname)
|
||||
deviceName := utils.Sanitize(request.DeviceName)
|
||||
|
||||
if utils.AdminOrItselfOnly(w, req, nickname) != nil {
|
||||
return
|
||||
}
|
||||
|
||||
c, errCo := utils.GetCollection(utils.GetRootAppId(), "devices")
|
||||
if errCo != nil {
|
||||
utils.Error("Database Connect", errCo)
|
||||
utils.HTTPError(w, "Database", http.StatusInternalServerError, "DB001")
|
||||
return
|
||||
}
|
||||
|
||||
device := utils.Device{}
|
||||
|
||||
utils.Debug("ConstellationDeviceBlocking: Blocking Device " + deviceName)
|
||||
|
||||
err2 := c.FindOne(nil, map[string]interface{}{
|
||||
"DeviceName": deviceName,
|
||||
"Nickname": nickname,
|
||||
"Blocked": false,
|
||||
}).Decode(&device)
|
||||
|
||||
if err2 == nil {
|
||||
utils.Debug("ConstellationDeviceBlocking: Found Device " + deviceName)
|
||||
|
||||
_, err3 := c.UpdateOne(nil, map[string]interface{}{
|
||||
"DeviceName": deviceName,
|
||||
"Nickname": nickname,
|
||||
}, map[string]interface{}{
|
||||
"$set": map[string]interface{}{
|
||||
"Blocked": request.Block,
|
||||
},
|
||||
})
|
||||
|
||||
if err3 != nil {
|
||||
utils.Error("DeviceBlocking: Error while updating device", err3)
|
||||
utils.HTTPError(w, "Device Creation Error: " + err3.Error(),
|
||||
http.StatusInternalServerError, "DB001")
|
||||
return
|
||||
}
|
||||
|
||||
if request.Block {
|
||||
utils.Log("ConstellationDeviceBlocking: Device " + deviceName + " blocked")
|
||||
} else {
|
||||
utils.Log("ConstellationDeviceBlocking: Device " + deviceName + " unblocked")
|
||||
}
|
||||
} else {
|
||||
utils.Error("DeviceBlocking: Error while finding device", err2)
|
||||
utils.HTTPError(w, "Device Creation Error: " + err2.Error(),
|
||||
http.StatusInternalServerError, "DB001")
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"status": "OK",
|
||||
})
|
||||
} else {
|
||||
utils.Error("DeviceBlocking: Method not allowed" + req.Method, nil)
|
||||
utils.HTTPError(w, "Method not allowed", http.StatusMethodNotAllowed, "HTTP001")
|
||||
return
|
||||
}
|
||||
}
|
|
@ -62,11 +62,12 @@ func DeviceCreate(w http.ResponseWriter, req *http.Request) {
|
|||
|
||||
err2 := c.FindOne(nil, map[string]interface{}{
|
||||
"DeviceName": deviceName,
|
||||
"Blocked": false,
|
||||
}).Decode(&device)
|
||||
|
||||
if err2 == mongo.ErrNoDocuments {
|
||||
|
||||
cert, key, err := generateNebulaCert(deviceName, request.IP, request.PublicKey, false)
|
||||
cert, key, fingerprint, err := generateNebulaCert(deviceName, request.IP, request.PublicKey, false)
|
||||
|
||||
if err != nil {
|
||||
utils.Error("DeviceCreation: Error while creating Device", err)
|
||||
|
@ -82,6 +83,13 @@ func DeviceCreate(w http.ResponseWriter, req *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
utils.Error("DeviceCreation: Error while getting fingerprint", err)
|
||||
utils.HTTPError(w, "Device Creation Error: " + err.Error(),
|
||||
http.StatusInternalServerError, "DC007")
|
||||
return
|
||||
}
|
||||
|
||||
_, err3 := c.InsertOne(nil, map[string]interface{}{
|
||||
"Nickname": nickname,
|
||||
"DeviceName": deviceName,
|
||||
|
@ -91,6 +99,7 @@ func DeviceCreate(w http.ResponseWriter, req *http.Request) {
|
|||
"IsRelay": request.IsRelay,
|
||||
"PublicHostname": request.PublicHostname,
|
||||
"Port": request.Port,
|
||||
"Fingerprint": fingerprint,
|
||||
})
|
||||
|
||||
if err3 != nil {
|
||||
|
|
|
@ -4,7 +4,7 @@ import (
|
|||
"net/http"
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
|
||||
"os"
|
||||
|
||||
"github.com/azukaar/cosmos-server/src/utils"
|
||||
)
|
||||
|
@ -81,11 +81,15 @@ func API_GetLogs(w http.ResponseWriter, req *http.Request) {
|
|||
}
|
||||
|
||||
if(req.Method == "GET") {
|
||||
|
||||
logs, err := os.ReadFile(utils.CONFIGFOLDER+"nebula.log")
|
||||
if err != nil {
|
||||
utils.Error("Error reading file:", err)
|
||||
return
|
||||
}
|
||||
|
||||
json.NewEncoder(w).Encode(map[string]interface{}{
|
||||
"status": "OK",
|
||||
"data": logBuffer.String(),
|
||||
"data": string(logs),
|
||||
})
|
||||
} else {
|
||||
utils.Error("SettingGet: Method not allowed" + req.Method, nil)
|
||||
|
|
|
@ -12,11 +12,12 @@ import (
|
|||
"strings"
|
||||
"io/ioutil"
|
||||
"strconv"
|
||||
"encoding/json"
|
||||
"io"
|
||||
"bytes"
|
||||
"github.com/natefinch/lumberjack"
|
||||
)
|
||||
|
||||
var logBuffer bytes.Buffer
|
||||
var logBuffer *lumberjack.Logger
|
||||
|
||||
var (
|
||||
process *exec.Cmd
|
||||
|
@ -38,16 +39,24 @@ func startNebulaInBackground() error {
|
|||
return errors.New("nebula is already running")
|
||||
}
|
||||
|
||||
logBuffer = &lumberjack.Logger{
|
||||
Filename: utils.CONFIGFOLDER+"nebula.log",
|
||||
MaxSize: 1, // megabytes
|
||||
MaxBackups: 1,
|
||||
MaxAge: 15, //days
|
||||
Compress: false,
|
||||
}
|
||||
|
||||
process = exec.Command(binaryToRun(), "-config", utils.CONFIGFOLDER+"nebula.yml")
|
||||
|
||||
// Set up multi-writer for stderr
|
||||
process.Stderr = io.MultiWriter(&logBuffer, os.Stderr)
|
||||
process.Stderr = io.MultiWriter(logBuffer, os.Stderr)
|
||||
|
||||
if utils.LoggingLevelLabels[utils.GetMainConfig().LoggingLevel] == utils.DEBUG {
|
||||
// Set up multi-writer for stdout if in debug mode
|
||||
process.Stdout = io.MultiWriter(&logBuffer, os.Stdout)
|
||||
process.Stdout = io.MultiWriter(logBuffer, os.Stdout)
|
||||
} else {
|
||||
process.Stdout = io.MultiWriter(&logBuffer)
|
||||
process.Stdout = io.MultiWriter(logBuffer)
|
||||
}
|
||||
|
||||
// Start the process in the background
|
||||
|
@ -125,6 +134,26 @@ func GetAllLightHouses() ([]utils.ConstellationDevice, error) {
|
|||
return devices, nil
|
||||
}
|
||||
|
||||
func GetBlockedDevices() ([]utils.ConstellationDevice, error) {
|
||||
c, err := utils.GetCollection(utils.GetRootAppId(), "devices")
|
||||
if err != nil {
|
||||
return []utils.ConstellationDevice{}, err
|
||||
}
|
||||
|
||||
var devices []utils.ConstellationDevice
|
||||
|
||||
cursor, err := c.Find(nil, map[string]interface{}{
|
||||
"Blocked": true,
|
||||
})
|
||||
cursor.All(nil, &devices)
|
||||
|
||||
if err != nil {
|
||||
return []utils.ConstellationDevice{}, err
|
||||
}
|
||||
|
||||
return devices, nil
|
||||
}
|
||||
|
||||
func cleanIp(ip string) string {
|
||||
return strings.Split(ip, "/")[0]
|
||||
}
|
||||
|
@ -133,10 +162,14 @@ func ExportConfigToYAML(overwriteConfig utils.ConstellationConfig, outputPath st
|
|||
// Combine defaultConfig and overwriteConfig
|
||||
finalConfig := NebulaDefaultConfig
|
||||
|
||||
finalConfig.StaticHostMap = map[string][]string{
|
||||
"192.168.201.1": []string{
|
||||
utils.GetMainConfig().ConstellationConfig.ConstellationHostname + ":4242",
|
||||
},
|
||||
if !overwriteConfig.PrivateNode {
|
||||
finalConfig.StaticHostMap = map[string][]string{
|
||||
"192.168.201.1": []string{
|
||||
utils.GetMainConfig().ConstellationConfig.ConstellationHostname + ":4242",
|
||||
},
|
||||
}
|
||||
} else {
|
||||
finalConfig.StaticHostMap = map[string][]string{}
|
||||
}
|
||||
|
||||
// for each lighthouse
|
||||
|
@ -151,6 +184,16 @@ func ExportConfigToYAML(overwriteConfig utils.ConstellationConfig, outputPath st
|
|||
}
|
||||
}
|
||||
|
||||
// add blocked devices
|
||||
blockedDevices, err := GetBlockedDevices()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, d := range blockedDevices {
|
||||
finalConfig.PKI.Blocklist = append(finalConfig.PKI.Blocklist, d.Fingerprint)
|
||||
}
|
||||
|
||||
// add other lighthouses
|
||||
finalConfig.Lighthouse.Hosts = []string{}
|
||||
for _, l := range lh {
|
||||
|
@ -334,7 +377,40 @@ func killAllNebulaInstances() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, error) {
|
||||
func GetCertFingerprint(certPath string) (string, error) {
|
||||
// nebula-cert print -json
|
||||
var cmd *exec.Cmd
|
||||
|
||||
cmd = exec.Command(binaryToRun() + "-cert",
|
||||
"print",
|
||||
"-json",
|
||||
"-path", certPath,
|
||||
)
|
||||
|
||||
// capture and parse output
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
utils.Error("Error while printing cert", err)
|
||||
}
|
||||
|
||||
var certInfo map[string]interface{}
|
||||
err = json.Unmarshal(output, &certInfo)
|
||||
if err != nil {
|
||||
utils.Error("Error while unmarshalling cert information", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Extract fingerprint, replace "fingerprint" with the actual key where the fingerprint is stored in the JSON output
|
||||
fingerprint, ok := certInfo["fingerprint"].(string)
|
||||
if !ok {
|
||||
utils.Error("Fingerprint not found or not a string", nil)
|
||||
return "", errors.New("fingerprint not found or not a string")
|
||||
}
|
||||
|
||||
return fingerprint, nil
|
||||
}
|
||||
|
||||
func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, string, error) {
|
||||
// Run the nebula-cert command
|
||||
var cmd *exec.Cmd
|
||||
|
||||
|
@ -348,9 +424,9 @@ func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, e
|
|||
)
|
||||
} else {
|
||||
// write PK to temp.cert
|
||||
err := ioutil.WriteFile("./temp.cert", []byte(PK), 0644)
|
||||
err := ioutil.WriteFile("./temp.key", []byte(PK), 0644)
|
||||
if err != nil {
|
||||
return "", "", fmt.Errorf("failed to write temp.cert: %s", err)
|
||||
return "", "", "", fmt.Errorf("failed to write temp.key: %s", err)
|
||||
}
|
||||
cmd = exec.Command(binaryToRun() + "-cert",
|
||||
"sign",
|
||||
|
@ -358,10 +434,10 @@ func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, e
|
|||
"-ca-key", utils.CONFIGFOLDER + "ca.key",
|
||||
"-name", name,
|
||||
"-ip", ip,
|
||||
"-in-pub", "./temp.cert",
|
||||
"-in-pub", "./temp.key",
|
||||
)
|
||||
// delete temp.cert
|
||||
defer os.Remove("./temp.cert")
|
||||
// delete temp.key
|
||||
defer os.Remove("./temp.key")
|
||||
}
|
||||
|
||||
utils.Debug(cmd.String())
|
||||
|
@ -377,7 +453,7 @@ func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, e
|
|||
cmd.Run()
|
||||
|
||||
if cmd.ProcessState.ExitCode() != 0 {
|
||||
return "", "", fmt.Errorf("nebula-cert exited with an error, check the Cosmos logs")
|
||||
return "", "", "", fmt.Errorf("nebula-cert exited with an error, check the Cosmos logs")
|
||||
}
|
||||
|
||||
// Read the generated certificate and key files
|
||||
|
@ -387,14 +463,19 @@ func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, e
|
|||
utils.Debug("Reading certificate from " + certPath)
|
||||
utils.Debug("Reading key from " + keyPath)
|
||||
|
||||
fingerprint, err := GetCertFingerprint(certPath)
|
||||
if err != nil {
|
||||
return "", "", "", fmt.Errorf("failed to get certificate fingerprint: %s", err)
|
||||
}
|
||||
|
||||
certContent, errCert := ioutil.ReadFile(certPath)
|
||||
if errCert != nil {
|
||||
return "", "", fmt.Errorf("failed to read certificate file: %s", errCert)
|
||||
return "", "", "", fmt.Errorf("failed to read certificate file: %s", errCert)
|
||||
}
|
||||
|
||||
keyContent, errKey := ioutil.ReadFile(keyPath)
|
||||
if errKey != nil {
|
||||
return "", "", fmt.Errorf("failed to read key file: %s", errKey)
|
||||
return "", "", "", fmt.Errorf("failed to read key file: %s", errKey)
|
||||
}
|
||||
|
||||
if saveToFile {
|
||||
|
@ -407,15 +488,15 @@ func generateNebulaCert(name, ip, PK string, saveToFile bool) (string, string, e
|
|||
} else {
|
||||
// Delete the generated certificate and key files
|
||||
if err := os.Remove(certPath); err != nil {
|
||||
return "", "", fmt.Errorf("failed to delete certificate file: %s", err)
|
||||
return "", "", "", fmt.Errorf("failed to delete certificate file: %s", err)
|
||||
}
|
||||
|
||||
if err := os.Remove(keyPath); err != nil {
|
||||
return "", "", fmt.Errorf("failed to delete key file: %s", err)
|
||||
return "", "", "", fmt.Errorf("failed to delete key file: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
return string(certContent), string(keyContent), nil
|
||||
return string(certContent), string(keyContent), fingerprint, nil
|
||||
}
|
||||
|
||||
func generateNebulaCACert(name string) (error) {
|
||||
|
|
|
@ -12,10 +12,12 @@ func InitConfig() {
|
|||
CA string `yaml:"ca"`
|
||||
Cert string `yaml:"cert"`
|
||||
Key string `yaml:"key"`
|
||||
Blocklist []string `yaml:"blocklist"`
|
||||
}{
|
||||
CA: utils.CONFIGFOLDER + "ca.crt",
|
||||
Cert: utils.CONFIGFOLDER + "cosmos.crt",
|
||||
Key: utils.CONFIGFOLDER + "cosmos.key",
|
||||
Blocklist: []string{},
|
||||
},
|
||||
StaticHostMap: map[string][]string{
|
||||
|
||||
|
|
|
@ -338,6 +338,7 @@ func InitServer() *mux.Router {
|
|||
srapi.HandleFunc("/api/constellation/connect", constellation.API_ConnectToExisting)
|
||||
srapi.HandleFunc("/api/constellation/config", constellation.API_GetConfig)
|
||||
srapi.HandleFunc("/api/constellation/logs", constellation.API_GetLogs)
|
||||
srapi.HandleFunc("/api/constellation/block", constellation.DeviceBlock)
|
||||
|
||||
if(!config.HTTPConfig.AcceptAllInsecureHostname) {
|
||||
srapi.Use(utils.EnsureHostname)
|
||||
|
|
|
@ -212,16 +212,22 @@ type MarketSource struct {
|
|||
type ConstellationConfig struct {
|
||||
Enabled bool
|
||||
SlaveMode bool
|
||||
PrivateNode bool
|
||||
DNS bool
|
||||
DNSPort string
|
||||
DNSFallback string
|
||||
DNSBlockBlacklist bool
|
||||
DNSAdditionalBlocklists []string
|
||||
CustomDNSEntries map[string]string
|
||||
CustomDNSEntries []ConstellationDNSEntry
|
||||
NebulaConfig NebulaConfig
|
||||
ConstellationHostname string
|
||||
}
|
||||
|
||||
type ConstellationDNSEntry struct {
|
||||
Type string
|
||||
Key string
|
||||
Value string
|
||||
}
|
||||
type ConstellationDevice struct {
|
||||
Nickname string `json:"nickname"`
|
||||
DeviceName string `json:"deviceName"`
|
||||
|
@ -231,6 +237,8 @@ type ConstellationDevice struct {
|
|||
IsRelay bool `json:"isRelay"`
|
||||
PublicHostname string `json:"publicHostname"`
|
||||
Port string `json:"port"`
|
||||
Blocked bool `json:"blocked"`
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
}
|
||||
|
||||
type NebulaFirewallRule struct {
|
||||
|
@ -251,6 +259,7 @@ type NebulaConfig struct {
|
|||
CA string `yaml:"ca"`
|
||||
Cert string `yaml:"cert"`
|
||||
Key string `yaml:"key"`
|
||||
Blocklist []string `yaml:"blocklist"`
|
||||
} `yaml:"pki"`
|
||||
|
||||
StaticHostMap map[string][]string `yaml:"static_host_map"`
|
||||
|
|
Loading…
Reference in a new issue