Skip to content

Commit

Permalink
Simplify osquery installation on non-YunoHost servers and move Advers…
Browse files Browse the repository at this point in the history
…aryMeter token generation to the User class.
  • Loading branch information
csavelief committed Sep 27, 2024
1 parent bf34de2 commit 842d2f5
Show file tree
Hide file tree
Showing 5 changed files with 117 additions and 124 deletions.
46 changes: 3 additions & 43 deletions app/Modules/AdversaryMeter/Helpers/AdversaryMeter.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,50 +10,10 @@ class AdversaryMeter
{
public static function redirectUrl(): string
{
$token = self::findAnyAdversaryMeterApiToken(Auth::user()); // TODO : throw an error if not set ?
/** @var User $user */
$user = Auth::user();
$token = $user->adversaryMeterApiToken(); // TODO : throw an error if not set ?
$url = app_url();
return asset('adversary_meter') . "/src/index.html?api_token={$token}&api_url={$url}";
}

private static function findAnyAdversaryMeterApiToken(User $user): ?string
{
if ($user->am_api_token) {
return $user->am_api_token;
}

$tenantId = $user->tenant_id;
$customerId = $user->customer_id;

if ($customerId) {

// Find the first user of this customer with an API token
$userTmp = User::where('customer_id', $customerId)
->where('tenant_id', $tenantId)
->whereNotNull('am_api_token')
->first();

if ($userTmp) {
return $userTmp->am_api_token;
}
}
if ($tenantId) {

// Find the first user of this tenant with an API token
$userTmp = User::where('tenant_id', $tenantId)
->whereNotNull('am_api_token')
->first();

if ($userTmp) {
return $userTmp->am_api_token;
}
}

$token = $user->createToken('adversarymeter', ['']);
$plainTextToken = $token->plainTextToken;

$user->am_api_token = $plainTextToken;
$user->save();

return $plainTextToken;
}
}
65 changes: 65 additions & 0 deletions app/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,71 @@ public function isCywiseUser(): bool
return $this->hasRole(Role::CYWISE_USER);
}

public function adversaryMeterApiToken(): ?string
{
if (!$this->canUseAdversaryMeter()) {
return null;
}
if ($this->am_api_token) {
return $this->am_api_token;
}

$tenantId = $this->tenant_id;
$customerId = $this->customer_id;

if ($customerId) {

// Find the first user of this customer with an API token
$userTmp = User::where('customer_id', $customerId)
->where('tenant_id', $tenantId)
->whereNotNull('am_api_token')
->first();

if ($userTmp) {
return $userTmp->am_api_token;
}
}
if ($tenantId) {

// Find the first user of this tenant with an API token
$userTmp = User::where('tenant_id', $tenantId)
->whereNotNull('am_api_token')
->first();

if ($userTmp) {
return $userTmp->am_api_token;
}
}

// This token will enable the user to configure AdversaryMeter through the user interface
$token = $this->createToken('adversarymeter', ['']);
$plainTextToken = $token->plainTextToken;

$this->am_api_token = $plainTextToken;
$this->save();

return $plainTextToken;
}

public function sentinelApiToken(): ?string
{
if (!$this->canManageServers()) {
return null;
}
if ($this->se_api_token) {
return $this->se_api_token;
}

// This token will enable the user to configure servers using curl
$token = $this->createToken('sentinel', []);
$plainTextToken = $token->plainTextToken;

$this->se_api_token = $plainTextToken;
$this->save();

return $plainTextToken;
}

public function canListServers(): bool
{
return $this->hasPermissionTo(Permission::LIST_SERVERS) || $this->canManageServers();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class AddSeApiTokenColumnInUsersTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->string('se_api_token')->nullable()->default(null);
});
}

/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('se_api_token');
});
}
}
38 changes: 14 additions & 24 deletions resources/views/home/cards/_summary.blade.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<div class="card-body">
<div class="row mt-3">
<div class="col">
AdversaryMeter est votre garde du corps numérique. Il veille sur vos <b>serveurs exposés sur Internet</b> en
AdversaryMeter est votre garde du corps numérique. <b>Il veille sur vos serveurs exposés sur Internet</b> en
détectant les vulnérabilités avant que des acteurs malveillants ne les exploitent.
</div>
</div>
Expand All @@ -34,38 +34,28 @@
<div class="card-body">
<div class="row mt-3">
<div class="col">
Sentinel est votre vigile numérique. Il surveille en continu <b>l'état de vos serveurs</b>, remontant
Sentinel est votre vigile numérique. <b>Il surveille en continu l'état de vos serveurs</b>, remontant
rapidement toute anomalie ou non-conformité afin de prévenir les risques avant qu'ils ne deviennent des
menaces réelles.
</div>
</div>
<div class="row mt-3">
<div class="col">
Pour configurer Sentinel :
Pour configurer Sentinel, connectez-vous en <i>root</i> au serveur que vous souhaitez surveiller et exécutez
cette ligne de commande :
<br><br>
<pre>
curl -s {{ app_url() }}/setup/script?api_token={{ Auth::user()->sentinelApiToken() }}&server_ip=<i>&lt;ip&gt;</i>&server_name=<i>&lt;name&gt;</i> | bash
</pre>
Avant d'exécuter celle-ci, assurez-vous que :<br><br>
<ul>
<li>
Dans votre navigateur, rendez-vous à l'adresse suivante pour obtenir un jeton d'accès : <br><br>
<b><a href="{{ app_url() }}/setup/token" target="_blank">{{ app_url() }}/setup/token</a></b>
<br><br>
Conservez-le soigneusement, il ne sera affiché qu'une seule fois !
<br><br>
</li>
<li>
Connectez vous en root au serveur que vous souhaitez surveiller et exécutez cette ligne de commande :
<br><br>
<b>curl -s {{ app_url() }}/setup/script?api_token=<i>&lt;token&gt;</i>&server_ip=<i>&lt;ip&gt;</i>&server_name=<i>&lt;name&gt;</i>
| bash</b>
<br><br>
Avant d'exécuter celle-ci, assurez-vous que :<br><br>
<ul>
<li><i>&lt;token&gt;</i> est bien remplacé par le jeton obtenu lors de l'étape précédente ;</li>
<li><i>&lt;ip&gt;</i> est bien remplacé par l'IP de votre serveur ;</li>
<li><i>&lt;name&gt;</i> est bien remplacé par une chaîne de caractères identifiant votre serveur
(optionnel).
</li>
</ul>
<li><i>&lt;ip&gt;</i> a bien été remplacé par l'IP de votre serveur ;</li>
<li><i>&lt;name&gt;</i> a bien été remplacé par une chaîne de caractères identifiant votre serveur
(optionnel).
</li>
</ul>
</li>
</ul>
</div>
</div>
</div>
Expand Down
60 changes: 3 additions & 57 deletions routes/web.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,55 +45,6 @@
return new JsonResponse($apps, 200, ['Access-Control-Allow-Origin' => '*']);
})->middleware('throttle:30,1');

Route::get('/setup/token', function (\Illuminate\Http\Request $request) {

/** @var User $user */
$user = $request->user();

if (!$user->canManageServers()) {
return new JsonResponse([
'status' => 'failure',
'message' => 'User must be able to manage servers.',
'user' => $user,
], 200, ['Access-Control-Allow-Origin' => '*']);
}

// Upon first connection, generate a user-specific 'system' token.
// This token will enable the user to configure servers using curl.
/** @var \Laravel\Sanctum\PersonalAccessToken $token */
$token = $user->tokens->where('name', 'system')->first();
$plainTextToken = null;

if (!$token) {
$token = $user->createToken('system', ['setup.sh']);
if (!$token) {
return new JsonResponse([
'status' => 'failure',
'message' => 'The token could not be generated.',
'user' => $user,
], 200, ['Access-Control-Allow-Origin' => '*']);
}
$plainTextToken = $token->plainTextToken;
$token = $token?->accessToken;
}
if ($token->cant('setup.sh')) {
$token->abilities = array_merge($token->abilities, ['setup.sh']);
$token->save();
}
if (!$plainTextToken) {
return new JsonResponse([
'status' => 'success',
'message' => 'A \'system\' token has already been generated. Please, reuse it.',
'token' => null,
], 200, ['Access-Control-Allow-Origin' => '*']);
}
return new JsonResponse([
'status' => 'success',
'message' => 'The \'system\' token has been generated.',
'token' => $plainTextToken,
], 200, ['Access-Control-Allow-Origin' => '*']);
})->middleware(['auth', 'throttle:6,1']);

Route::get('/setup/script', function (\Illuminate\Http\Request $request) {

$token = $request->input('api_token');
Expand All @@ -106,7 +57,7 @@
/** @var \Laravel\Sanctum\PersonalAccessToken $token */
$token = \Laravel\Sanctum\PersonalAccessToken::findToken($token);

if (!$token || $token->cant('setup.sh')) {
if (!$token) {
return response('Invalid token', 403)
->header('Content-Type', 'text/plain');
}
Expand Down Expand Up @@ -167,13 +118,8 @@
$server->added_with_curl = true;
$server->save();

// 1. In the browser, go to "https://app.towerify.io" and login using your user account.
// 2. In the browser, go to "https://app.towerify.io/setup/token" to get a user-specific cURL token.
// 3. On the server, run:
// 3.1 curl -s https://app.towerify.io/setup/script?api_token=<token>&server_ip=<ip>&server_name=<name> >install.sh
// 3.2 chmod +x install.sh
// 3.3 ./install.sh
// 3.4 rm install.sh
// 1. In the browser, go to "https://app.towerify.io" and login using your user account
// 2. On the server, run as root: curl -s https://app.towerify.io/setup/script?api_token=<token>&server_ip=<ip>&server_name=<name> | bash
$installScript = \App\Models\YnhOsquery::monitorServer($server);

return response($installScript, 200)
Expand Down

0 comments on commit 842d2f5

Please sign in to comment.